home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 February: Technology Seed / Mac Tech Seed Feb '97.toast / OpenDoc 1.2b2c1 / Implementation / DocShell / RlShlEv.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1997-02-13  |  69.3 KB  |  2,443 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        RlShlEv.cpp
  3.  
  4.     Contains:    Apple Event handlers for the document shell.
  5.  
  6.     Owned by:    Eric House
  7.  
  8.     Copyright:    © 1994 - 1997 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.  
  12.         <11>      1/8/97    DH        1401434: Deal with deactivating and
  13.                                     reactivating OD windows when dialogs are
  14.                                     shown; make sure size is correct in dialog
  15.                                     to change doc size;
  16.         <10>      12/17/96    CSL        1611512: Don't call UpdateMenus from
  17.                                     HandleHighLevelEvent.
  18.          <9>      10/23/96    DH        Fixed build break from previous checkin.
  19.          <8>      10/23/96    DH        Removed heap validation code from previous
  20.                                     checkin.
  21.          <7>      10/22/96    DH        1336808,1333949,1368888,1375780    Added new
  22.                                     event to change the size of a document,
  23.                                     including code to displays controls to do
  24.                                     so.
  25.          <6>    20.09.1996    NP        386083: Add include
  26.          <5>     7/11/96    TJ        Quit event does not return an error
  27.          <4>     6/20/96    JP        1339269: Made quit handle the saving
  28.                                     parameter too
  29.          <3>     5/31/96    jpa        T10012: Fixed 'oapp', 'odoc', 'pdoc'
  30.                                     handlers for app-style (CyberDog) process
  31.                                     model.
  32.          <2>      5/8/96    NP        1304875: Infinite Save Changes dialog boxes
  33.  
  34.     To Do:
  35.     In Progress:
  36.         
  37. */
  38.  
  39. #ifndef _PLFMDEF_
  40. #include <PlfmDef.h>
  41. #endif
  42.  
  43. #ifndef _SIHELPER_
  44. #include <SIHelper.h>
  45. #endif
  46.  
  47. #ifndef _ODPRCS_
  48. #include "ODPrcs.h"
  49. #endif
  50.  
  51. #ifndef SOM_ODSession_xh
  52. #include <ODSessn.xh>
  53. #endif
  54.  
  55. #ifndef _EXCEPT_
  56. #include <Except.h>
  57. #endif
  58.  
  59. #ifndef SOM_ShellSI_xh
  60. #include "ShellSI.xh"
  61. #endif
  62.  
  63. #ifndef _RLSHELL_
  64. #include "RlShell.h"
  65. #endif
  66.  
  67. #ifndef _SEUTILS_
  68. #include <SEUtils.h>
  69. #endif
  70.  
  71. #ifndef _SHPRPACC_
  72. #include "ShPrpAcc.h"
  73. #endif
  74.  
  75. #ifndef _SHLEVTHD_
  76. #include "ShlEvtHd.h"
  77. #endif
  78.  
  79. #ifndef _USERSRCM_
  80. #include <UseRsrcM.h>
  81. #endif
  82.  
  83. #ifndef _RLSHELL_
  84. #include "RlShell.h"
  85. #endif
  86.  
  87. #ifndef SOM_ODContainer_xh
  88. #include <ODCtr.xh>
  89. #endif
  90.  
  91. #ifndef _ODUTILS_
  92. #include <ODUtils.h>
  93. #endif
  94.  
  95. #ifndef _DOCUTILS_
  96. #include <DocUtils.h>
  97. #endif
  98.  
  99. #ifndef __ALIASES__
  100. #include <Aliases.h>
  101. #endif
  102.  
  103. #ifndef _PLFMFILE_
  104. #include <PlfmFile.h>
  105. #endif
  106.  
  107. #ifndef _ODDESUTL_
  108. #include <ODDesUtl.h>
  109. #endif
  110.  
  111. #ifndef SOM_ODDocument_xh
  112. #include <Document.xh>
  113. #endif
  114.  
  115. #ifndef SOM_ODNameResolver_xh
  116. #include <NamRslvr.xh>
  117. #endif
  118.  
  119. #ifndef SOM_ODWindowState_xh
  120. #include <WinStat.xh>
  121. #endif
  122.  
  123. #ifndef SOM_ODWindow_xh
  124. #include <Window.xh>
  125. #endif
  126.  
  127. #ifndef SOM_ODMessageInterface_xh
  128. #include <MssgIntf.xh>
  129. #endif
  130.  
  131. #ifndef SOM_ODDispatcher_xh
  132. #include <Disptch.xh>
  133. #endif
  134.  
  135. #ifndef SOM_ODWindowIterator_xh
  136. #include <WinIter.xh>
  137. #endif
  138.  
  139. #ifndef SOM_ODOSLToken_xh
  140. #include <ODOSLTkn.xh>
  141. #endif
  142.  
  143. #ifndef SOM_ODAppleEvent_xh
  144. #include <ODAplEvt.xh>
  145. #endif
  146.  
  147. #ifndef _SHELLDEF_
  148. #include <ShellDef.h>
  149. #endif
  150.  
  151. #ifndef __ASREGISTRY__
  152. #include <ASRegistry.h>
  153. #endif
  154.  
  155. #ifndef __AEUserTermTypes__
  156. #include <AEUserTermTypes.h>
  157. #endif
  158.  
  159. #ifndef __APPLEEVENTS__
  160. #include <AppleEvents.h>
  161. #endif
  162.  
  163. #ifndef SOM_Module_OpenDoc_ODRegistry_defined
  164. #include "ODRgstry.xh"
  165. #endif
  166.  
  167. #ifndef __RESOURCES__
  168. #include <Resources.h>
  169. #endif
  170.  
  171. #ifndef _ODDEBUG_
  172. #include "ODDebug.h"
  173. #endif
  174.  
  175. #ifndef _TEMPOBJ_
  176. #include "TempObj.h"
  177. #endif
  178.  
  179. #ifndef _DOCUTILP_
  180. #include "DocUtilP.h"
  181. #endif
  182.  
  183. #ifndef SOM_Module_OpenDoc_StdDefs_defined
  184. #include <StdDefs.xh>
  185. #endif
  186.  
  187. #ifndef __TOOLUTILS__
  188. #include <ToolUtils.h>
  189. #endif
  190.  
  191. #ifndef __ICONS__
  192. #include <Icons.h>
  193. #endif
  194.  
  195. #ifndef __PALETTES__
  196. #include <Palettes.h>
  197. #endif
  198.  
  199. #ifndef _MEMDEBG_
  200. #include "MemDebg.h"
  201. #endif
  202.  
  203. #ifndef _SHELLDEF_
  204. #include "ShellDef.h"
  205. #endif
  206.  
  207. #ifndef _WINUTILM_
  208. #include "WinUtilM.h" 
  209. #endif
  210.  
  211. #pragma segment ShellEvt
  212.  
  213. //==============================================================================
  214. // Constants
  215. //==============================================================================
  216.  
  217. #define STATICBUILD
  218.  
  219. const DescType kShellPropAccessor         = 0x73706163;    // 'spac';
  220. const DescType kShellSelfPropAccessor    = 0x7368656C;    // 'shel';
  221.  
  222. const DescType kShellEventHandler = 'shev';
  223.  
  224. const ODSize kDocSizeHighAlert    = 128;
  225. const ODSize kFatalLowAppAlert    = 131;
  226. const ODSize kLowAppMemAlert    = 132;
  227.  
  228. const short    kNormalIconID        = 128;
  229. const short    kUpArrowIconID        = 129;
  230. const short    kDownArrowIconID    = 130;
  231.  
  232. const short kDecreaseMemBtn        = 2;
  233.  
  234. enum {
  235.     kOKButton = 1,
  236.     kCancelButton,            // 2
  237.     kArrowBottom,            // 3
  238.     kArrowTop,                // 4
  239.     kArrowControl,            // 5
  240.     kNewDocHeapPrefSizeFld,    // 6
  241.     kCurDocHeapPrefSizeFld,    // 7
  242.     kCurrentKText,            // 8 new "K"
  243.     kNewKText,                // 9 current "K"
  244.     kSaveChangesTxtItem=13    // 13 ; Save changes text item.
  245. };
  246.  
  247. const unsigned long kSizeIncrement        = (32 * 1024);
  248. const unsigned long kMaximumSize        = (1024 * 1024 * 64);
  249. const short kControlInactive            = 255;
  250. const short kControlActive                = 0;
  251. const short kDefaultDocSizeRes            = -1;
  252. //==============================================================================
  253. // Globals
  254. //==============================================================================
  255.  
  256. extern     ODULong    gSize         = 0;
  257.         ODULong    gOrigDocSize = 0;
  258.         
  259. pascal void MyUserItemProc (DialogPtr dlog, short item);
  260. UserItemUPP        gUserItemUPP = NewUserItemProc (MyUserItemProc);
  261.  
  262. //==============================================================================
  263. // Function Prototypes
  264. //==============================================================================
  265.  
  266. //void    CreateUniqueTmpFolderForFile(ODFileSpec* result, Str63 fileName);
  267.  
  268. #define HANDLER_PARAMS                                                     \
  269.     ODPart* thePart,                                                     \
  270.     ODAppleEvent* message,                                                 \
  271.      ODAppleEvent* reply,                                                 \
  272.     ODSLong handlerRefcon
  273.  
  274. // pascal ODError HandleClone(HANDLER_PARAMS);
  275. pascal ODError HandleClose(HANDLER_PARAMS);
  276. // pascal ODError HandleCountEl(HANDLER_PARAMS);
  277. // pascal ODError HandleMake(HANDLER_PARAMS);
  278. // pascal ODError HandleDelete(HANDLER_PARAMS);
  279. // pascal ODError HandleDoExist(HANDLER_PARAMS);
  280. // pascal ODError HandleGetClsInfo(HANDLER_PARAMS);
  281. // pascal ODError HandleGetData(HANDLER_PARAMS);
  282. // pascal ODError HandleGetDataSz(HANDLER_PARAMS);
  283. // pascal ODError HandleGetEvnInfo(HANDLER_PARAMS);
  284. // pascal ODError HandleMove(HANDLER_PARAMS);
  285. // pascal ODError HandleOpen(HANDLER_PARAMS);
  286. // pascal ODError HandlePrint(HANDLER_PARAMS);
  287. pascal ODError HandleSave(HANDLER_PARAMS);
  288. // pascal ODError HandleSetData(HANDLER_PARAMS);
  289. pascal ODError HandleODActivate(HANDLER_PARAMS);
  290.  
  291. pascal ODError HandleGetAETE(HANDLER_PARAMS);
  292.  
  293. #undef HANDLER_PARAMS
  294.                 
  295. pascal ODError GetFileFromNULL(    ODPart*                part,
  296.                                 DescType            desiredClass,
  297.                                 ODOSLToken*            container,
  298.                                 DescType            containerClass,
  299.                                 DescType            form,
  300.                                 ODDesc*                selectionData,
  301.                                 ODOSLToken*            value,
  302.                                 ODSLong                refCon);
  303.  
  304.  
  305. ShellEventHandler* GetHandlerFromAEVT(AppleEvent* theAppleEvent,
  306.         RealShell* self);
  307. void GetDirectParam(RealShell* self, AppleEvent* theAppleEvent,
  308.         AEDesc* evtDp);
  309.  
  310. static ODBoolean    AskUserIncreaseDocSize(FSSpec* theFSSpec);
  311. static void            DoDialogSetup( DialogPtr dialog, PlatformFile* docFile);
  312. static Boolean         DoDialogHits(DialogPtr dialog, short itemHit, ODBoolean increaseSize,
  313.                                  ODBoolean fatalLowMem);
  314. static void         SetDialogMemorySize (DialogPtr dlog, Size size);
  315. pascal void         MyUserItemProc (DialogPtr dlog, short item);
  316. static void         DoMemorySettingHits(DialogPtr dialog, short itemHit, ODBoolean increaseSize,
  317.                                         ODBoolean fatalLowMem);
  318. ODStatic void        DHSetDocumentPreferredHeapSize(PlatformFile* file, ODULong numKBytes);
  319. ODStatic ODULong    DHGetDocumentPreferredHeapSize(PlatformFile* file);
  320. static ODULong        DHGetPreferredSizeInSIZE(PlatformFile* file, ODSShort resourceID);
  321. static void         DHSetPreferredSizeInSIZE(PlatformFile* file, ODSShort resourceID, 
  322.                         PlatformFile* fromFile, ODSShort fromResID, ODULong numKBytes);
  323. static void         AttachUserItemProc (DialogPtr dlog, short item, UserItemUPP proc);
  324. static void         PlotArrowIcon(DialogPtr dlog, short item);
  325. static void         SetNumText(DialogPtr dlg, ODSShort item, ODSLong numValue);
  326. static OSErr         ReplaceTempSizeWithSize( short id );
  327. static void         ODOutlineDefaultButtonDrawProc(DialogPtr theDialog, short theItem);
  328.  
  329. //==============================================================================
  330. // RealShell
  331. //==============================================================================
  332.  
  333. //-------------------------------------------------------------------------------------
  334. // Apple Event Initialization
  335. //-------------------------------------------------------------------------------------
  336.  
  337.  
  338. void RealShell::InitAE()
  339. {
  340.     Environment* ev = fEV;
  341.  
  342.     ShellSI* shellSemtInterface = new ShellSI;
  343.     THROW_IF_NULL(shellSemtInterface);
  344.     fSIHelper = new SIHelper;
  345.     fSIHelper->InitSIHelper(fSession, shellSemtInterface);
  346.     shellSemtInterface->InitCPlusSemanticInterface(ev, kODAppShell, fSIHelper,
  347.                                                 fSession);
  348.     fSession->SetShellSemtInterface(ev, shellSemtInterface);
  349.     shellSemtInterface->Release(ev); // SetShellSemtInterface acquires.
  350.  
  351.     ODObjectAccessorUPP newAccessor = 
  352.             NewODObjectAccessorProc( GetFileFromNULL );
  353.     ((SIHelper*)shellSemtInterface->GetSIHelper(ev))->InstallObjectAccessor( cFile, 
  354.                                         typeNull, newAccessor, (ODSLong)fSession );
  355.                                 
  356.     ODEventHandlerUPP newHandler = 
  357.             NewODEventHandlerProc( RealShell::HandleOpenAppEvent );
  358.     ((SIHelper*)shellSemtInterface->GetSIHelper(ev))->InstallEventHandler( kCoreEventClass,
  359.                                 kAEOpenApplication,
  360.                                 newHandler,
  361.                                 (long)this);
  362.                                 
  363.     newHandler = NewODEventHandlerProc( RealShell::HandleOpenPrintDocsEvent );
  364.     ((SIHelper*)shellSemtInterface->GetSIHelper(ev))->InstallEventHandler( kCoreEventClass,
  365.                                 kAEOpenDocuments,
  366.                                 newHandler,
  367.                                 (long)this);
  368.                                 
  369.     newHandler = NewODEventHandlerProc( RealShell::HandleOpenPrintDocsEvent );
  370.     ((SIHelper*)shellSemtInterface->GetSIHelper(ev))->InstallEventHandler( kCoreEventClass,
  371.                                 kAEPrintDocuments,
  372.                                 newHandler ,
  373.                                 (long)this);
  374.                                 
  375.     newHandler = NewODEventHandlerProc( RealShell::HandleQuitEvent );
  376.     ((SIHelper*)shellSemtInterface->GetSIHelper(ev))->InstallEventHandler( kCoreEventClass,
  377.                                 kAEQuitApplication,
  378.                                 newHandler ,
  379.                                 (long)this);
  380.  
  381.     newHandler = NewODEventHandlerProc( RealShell::HandleLaunchFailedEvent );
  382.     ((SIHelper*)shellSemtInterface->GetSIHelper(ev))->InstallEventHandler(
  383.                                 kCFMLaunchFailedEventClass,
  384.                                 kCFMLaunchFailedEventID,
  385.                                 newHandler ,
  386.                                 (long)this);
  387.  
  388.     newHandler = NewODEventHandlerProc( RealShell::HandleODActivate );
  389.     ((SIHelper*)shellSemtInterface->GetSIHelper(ev))->InstallEventHandler(
  390.                                 kAEOpenDocSuite,
  391.                                 kODActivateEvent,
  392.                                 newHandler ,
  393.                                 (long)this);
  394.  
  395.     newHandler = NewODEventHandlerProc( RealShell::HandleDocSizeChangeInteraction );
  396.     ((SIHelper*)shellSemtInterface->GetSIHelper(ev))->InstallEventHandler(
  397.                                 'dumb',
  398.                                 'hack',
  399.                                 newHandler ,
  400.                                 (long)this);
  401.  
  402.     ODCoercionHandlerUPP fsSpecCoerceHdlr =
  403.             NewODDescCoercionHandlerProc( RealShell::CoerceToFSSpec );
  404.     ((SIHelper*)shellSemtInterface->GetSIHelper(ev))->InstallCoercionHandler( typeAlias, typeFSS,
  405.             fsSpecCoerceHdlr, (long)this, kODTrue );
  406.                                 
  407. //    this->InstallObjectAccessors(shellSemtInterface);
  408.     
  409. /*
  410. ((SIHelper*)shellSemtInterface->GetSIHelper(ev))->InstallCoercionHandler(typeChar, typeFSS,
  411.                                 (XMPCoercionHandler)Pathname2FSSpec, kNoRefCon,
  412.                                 kFromTypeIsNotDesc );
  413. */
  414.  
  415.     ODEventHandlerUPP eventHandlerUPP;
  416.     
  417. #ifdef TO_BE_DELETED
  418.     eventHandlerUPP = NewODEventHandlerProc(HandleClone);
  419.     ((SIHelper*)shellSemtInterface->GetSIHelper(ev))->InstallEventHandler(kAECoreSuite, kAEClone,
  420.             eventHandlerUPP, (ODSLong)this);
  421. #endif /* TO_BE_DELETED */
  422.     
  423.     eventHandlerUPP = NewODEventHandlerProc(HandleClose);
  424.     ((SIHelper*)shellSemtInterface->GetSIHelper(ev))->InstallEventHandler(kAECoreSuite, kAEClose,
  425.             eventHandlerUPP, (ODSLong)this);
  426.     
  427. #ifdef TO_BE_DELETED
  428.     eventHandlerUPP = NewODEventHandlerProc(HandleCountEl);
  429.     ((SIHelper*)shellSemtInterface->GetSIHelper(ev))->InstallEventHandler(kAECoreSuite, kAECountElements,
  430.             eventHandlerUPP, (ODSLong)this);
  431.  
  432.     eventHandlerUPP = NewODEventHandlerProc(HandleMake);
  433.     ((SIHelper*)shellSemtInterface->GetSIHelper(ev))->InstallEventHandler(kAECoreSuite, kAECreateElement,
  434.             eventHandlerUPP, (ODSLong)this);
  435.     
  436.     eventHandlerUPP = NewODEventHandlerProc(HandleDelete);
  437.     ((SIHelper*)shellSemtInterface->GetSIHelper(ev))->InstallEventHandler(kAECoreSuite, kAEDelete,
  438.             eventHandlerUPP, (ODSLong)this);
  439.         
  440.     eventHandlerUPP = NewODEventHandlerProc(HandleDoExist);
  441.     ((SIHelper*)shellSemtInterface->GetSIHelper(ev))->InstallEventHandler(kAECoreSuite, kAEDoObjectsExist,
  442.             eventHandlerUPP, (ODSLong)this);
  443.         
  444.     eventHandlerUPP = NewODEventHandlerProc(HandleGetClsInfo);
  445.     ((SIHelper*)shellSemtInterface->GetSIHelper(ev))->InstallEventHandler(kAECoreSuite, kAEGetClassInfo,
  446.             eventHandlerUPP, (ODSLong)this);
  447.         
  448.     eventHandlerUPP = NewODEventHandlerProc(HandleGetData);
  449.     ((SIHelper*)shellSemtInterface->GetSIHelper(ev))->InstallEventHandler(kAECoreSuite, kAEGetData,
  450.             eventHandlerUPP, (ODSLong)this);
  451.         
  452.     eventHandlerUPP = NewODEventHandlerProc(HandleGetDataSz);
  453.     ((SIHelper*)shellSemtInterface->GetSIHelper(ev))->InstallEventHandler(kAECoreSuite, kAEGetDataSize,
  454.             eventHandlerUPP, (ODSLong)this);
  455.         
  456.     eventHandlerUPP = NewODEventHandlerProc(HandleGetEvnInfo);
  457.     ((SIHelper*)shellSemtInterface->GetSIHelper(ev))->InstallEventHandler(kAECoreSuite, kAEGetEventInfo,
  458.             eventHandlerUPP, (ODSLong)this);
  459.         
  460.     eventHandlerUPP = NewODEventHandlerProc(HandleMove);
  461.     ((SIHelper*)shellSemtInterface->GetSIHelper(ev))->InstallEventHandler(kAECoreSuite, kAEMove,
  462.             eventHandlerUPP, (ODSLong)this);
  463.         
  464.     eventHandlerUPP = NewODEventHandlerProc(HandleOpen);
  465.     ((SIHelper*)shellSemtInterface->GetSIHelper(ev))->InstallEventHandler(kAECoreSuite, kAEOpen,
  466.             eventHandlerUPP, (ODSLong)this);
  467.         
  468.     eventHandlerUPP = NewODEventHandlerProc(HandlePrint);
  469.     ((SIHelper*)shellSemtInterface->GetSIHelper(ev))->InstallEventHandler(kAECoreSuite, kAEPrint,
  470.             eventHandlerUPP, (ODSLong)this);
  471. #endif /* TO_BE_DELETED */
  472.         
  473.     eventHandlerUPP = NewODEventHandlerProc(HandleSave);
  474.     ((SIHelper*)shellSemtInterface->GetSIHelper(ev))->InstallEventHandler(kAECoreSuite, kAESave,
  475.             eventHandlerUPP, (ODSLong)this);
  476.         
  477. #ifdef TO_BE_DELETED
  478.     eventHandlerUPP = NewODEventHandlerProc(HandleSetData);
  479.     ((SIHelper*)shellSemtInterface->GetSIHelper(ev))->InstallEventHandler(kAECoreSuite, kAESetData,
  480.             eventHandlerUPP, (ODSLong)this);
  481. #endif /* TO_BE_DELETED */
  482.  
  483. //#ifndef STATICBUILD
  484.     // Just let AS get the resource directly if not ASLM.  In fact, we
  485.     // probably don't need this even in that case.
  486.     eventHandlerUPP = NewODEventHandlerProc(HandleGetAETE);
  487.     ((SIHelper*)shellSemtInterface->GetSIHelper(ev))->InstallEventHandler(kAEOpenDocSuite, kGetAETE,
  488.                                                 eventHandlerUPP,
  489.                                                 (ODSLong)this);
  490. //#endif /* STATICBUILD */
  491.  
  492. }
  493.  
  494.  
  495. void RealShell::HandleHighLevelEvent(ODEventData* event)
  496. {
  497.     Environment* ev = fEV;
  498.  
  499.     if ( ((AEEventClass) event->message == 'aevt') && (*(AEEventID *) &(event->where) == 'odoc') )
  500.     {
  501.         // If the open document event was sent by the edition manager, the modifiers field
  502.         // of the event will be garbage.  This can cause AEProcessAppleEvent to return an error
  503.         // instead of calling one of our event handlers.
  504.         // We work around this by clearing the modifiers field.  Note that clearing the field
  505.         // is not correct if the event is larger than 64K; we take the chance that an 'odoc'
  506.         // event won't be this large. [cc 7/19/95] [Radar #1261856]
  507.         event->modifiers = 0;
  508.     }
  509.  
  510.     ODBoolean succeeded = fSession->GetMessageInterface(ev)->ProcessSemanticEvent(ev, event);
  511. }
  512.  
  513.  
  514. //-------------------------------------------------------------------------------------
  515. // Handling 'oapp' Events
  516. //-------------------------------------------------------------------------------------
  517.  
  518.  
  519. pascal ODError RealShell::HandleOpenAppEvent(ODPart* part,
  520.                                         ODAppleEvent* message,
  521.                                         ODAppleEvent* reply,
  522.                                         long refCon)
  523. {
  524.     /*    Called when a stub application is starting up the OpenDoc shell
  525.         at launch time -- e.g. CyberDog. */
  526.         
  527. ODUnused(part);
  528. ODUnused(message);
  529. ODUnused(reply);
  530.  
  531.     RealShell*    self = (RealShell*)refCon;
  532.     Environment* ev = self->fEV;
  533.     ODError    error = noErr;
  534.  
  535.     TRY
  536.  
  537.         // Determine location (FSSpec) of current app:
  538.         ProcessInfoRec info;
  539.         FSSpec appLoc;
  540.         self->GetCurrentProcessInfo(&info,NULL,&appLoc);
  541.         
  542.         TempPlatformFile file = new PlatformFile;
  543.         file->Specify(&appLoc);
  544.         self->OpenFile(file,kODTrue);    // Force it to open APPL
  545.     
  546.     CATCH_ALL
  547.         error = ErrorCode();
  548.         self->GetSession()->GetDispatcher(ev)->Exit(ev);
  549.         self->SetAEError(error);
  550.     ENDTRY
  551.  
  552.     return error;
  553. }
  554.  
  555.  
  556. //-------------------------------------------------------------------------------------
  557. // Handling 'odoc' and 'pdoc' Events
  558. //-------------------------------------------------------------------------------------
  559.  
  560.  
  561. void RealShell::FakePrintMenuEvent()
  562. {
  563.     Environment* ev = fEV;
  564.     ODDispatcher* dispatcher = this->GetSession()->GetDispatcher(ev);
  565.     
  566.     ODMenuID menu;
  567.     ODMenuItemID menuItem;
  568.     TempODMenuBar baseMenuBar = this->fWindowState->AcquireBaseMenuBar(ev);
  569.     baseMenuBar->GetMenuAndItem(ev, kODCommandPrint, &menu, &menuItem );
  570.     
  571.     ODEventData event;
  572.     event.message = (menu<<16) | menuItem;
  573.     event.what = kODEvtMenu;
  574.     // zero the rest of the fields
  575.     WASSERT( sizeof(Point) == sizeof(long) );    // this is gross but
  576.     *(long*)&event.where = 0L;
  577.     event.when = 0L;
  578.     event.modifiers = 0;
  579.     dispatcher->Dispatch(ev, &event);
  580. }
  581.  
  582.  
  583. pascal ODError RealShell::HandleOpenPrintDocsEvent(    ODPart* part,
  584.                                             ODAppleEvent* message,
  585.                                             ODAppleEvent* reply,
  586.                                             long refCon)
  587. {
  588. ODUnused(part);
  589. ODUnused(reply);
  590.  
  591.     RealShell*    self = (RealShell*)refCon;
  592.     Environment* ev = self->fEV;
  593.     ODSession* session = self->GetSession();
  594.     ODVolatile(session);
  595.     
  596.     long        itemsInList;
  597.     ODError    error = noErr;
  598.     AppleEvent    realMessage;
  599.     DescType eventID;
  600.     DescType ignoreType;
  601.     Size ignoreActual;
  602.  
  603.     TRY
  604.     
  605.     // get list of documents
  606.     realMessage.dataHandle = kODNULL;
  607.     THROW_IF_ERROR( ODDescToAEDesc(message, &realMessage));
  608.     TempAEDescStruct docList;
  609.     THROW_IF_ERROR(AEGetParamDesc(&realMessage, keyDirectObject, typeAEList,
  610.             &docList));
  611.     THROW_IF_ERROR( AEGetAttributePtr( &realMessage, keyEventIDAttr, typeType,
  612.             &ignoreType, &eventID, sizeof(eventID), &ignoreActual ));
  613.     ODBoolean isPrint = eventID == kAEPrintDocuments;
  614.     if (MissingParams(&realMessage))
  615.         THROW( errAEParamMissed );
  616.     
  617.     // Iterate through all documents and open them:
  618.     THROW_IF_ERROR( AECountItems(&docList, &itemsInList ));
  619.     for (ODSLong index = 1; index <= itemsInList; index++) {
  620.         
  621.         ODFileSpec fileSpec;
  622.         AEKeyword key,type;
  623.         Size size;
  624.         OSErr err = AEGetNthPtr(&docList, index, typeFSS, &key,&type,
  625.                                 &fileSpec,sizeof(fileSpec),&size);
  626.         if (err == errAECoercionFail)
  627.         {
  628.             // We'll handle tokens here...
  629.             TempAEDescStruct coerceDesc, fileDesc;
  630.             ODOSLToken* tmpWrapper = new ODOSLToken();
  631.             THROW_IF_NULL(tmpWrapper);
  632.             TempODObject tempObj(tmpWrapper);
  633.             tmpWrapper->InitODOSLToken(ev);
  634.  
  635.             GetDirectParam(self, &realMessage, &coerceDesc);
  636.             THROW_IF_ERROR( AEDescToODDesc(&coerceDesc, tmpWrapper ) );
  637.             ODDesc* myToken;
  638.             ODNameResolver*    resolver = session->GetNameResolver(ev);
  639.             myToken = resolver->GetUserToken(ev, tmpWrapper);
  640.             AEDisposeDesc( &coerceDesc );
  641.             THROW_IF_ERROR( ODDescToAEDesc(myToken, &coerceDesc) );
  642.             THROW_IF_ERROR( AECoerceDesc(&coerceDesc, typeFSS, &fileDesc) );
  643.             ODBlockMove(*fileDesc.dataHandle,&fileSpec,sizeof(fileSpec));
  644.             err = noErr;
  645.         }
  646.         
  647.         // If printing, open each document in this process, then print and close it.
  648.         // If this is an application process (CyberDog), open all documents in this process.
  649.         // If this is a normal document process, open the first document in this process
  650.         //        if no document is open, and open the rest in separate processes.
  651.         if( !err ) {
  652.             TempPlatformFile file = new PlatformFile();
  653.             file->Specify(&fileSpec);
  654.             if( isPrint ) {
  655.                 ODDocument *doc = self->OpenFile(file);
  656.                 if( doc ) {
  657.                     self->FakePrintMenuEvent();
  658.                     if (ODCloseDocument(ev, session, doc))
  659.                         session->GetDispatcher(ev)->Exit(ev);
  660.                 }
  661.             } else if( self->fAPPLProcess || (index==1 && ODGetFirstOpenDocument(ev, session)==kODNULL) )
  662.                 self->OpenFile(file);
  663.             else
  664.                 self->OpenAnotherFile(file);
  665.         }
  666.     }
  667.  
  668.     CATCH_ALL
  669.         error = ErrorCode();
  670.         session->GetDispatcher(ev)->Exit(ev);
  671.         self->SetAEError(error);
  672.     ENDTRY
  673.     ODDisposeAppleEvent( &realMessage );
  674.  
  675.     return error;
  676. }    // HandleOpenPrintDocsEvent()
  677.  
  678. ////////////////////////////////////////////////////////////////////////////////
  679. //
  680. //        HandleQuitEvent
  681. //
  682. ////////////////////////////////////////////////////////////////////////////////
  683.  
  684. pascal ODError RealShell::HandleQuitEvent(    ODPart* /*part*/,
  685.                                         ODAppleEvent* message,
  686.                                         ODAppleEvent* /*reply*/,
  687.                                         long refCon)
  688. {
  689.     ODError            error        = noErr;
  690.     RealShell*        self        = (RealShell*)refCon;
  691.     Environment*    ev            = self->fEV;
  692.     ODSession*        session        = self->GetSession();
  693.     ODDescType        yesNoAsk    = kAEAsk;
  694.     ODDescType        theType;
  695.     ODSLong            theSize;
  696.     AEDesc            event;
  697.  
  698.     TRY
  699.         ODDescToAEDesc(message, &event);
  700.         error = AEGetParamPtr(&event, keyAESaveOptions, typeEnumerated, &theType, &yesNoAsk, sizeof(yesNoAsk), &theSize);
  701.         // we don't throw because we're quitting and don't care if there's an error
  702.         error = noErr;  // to keep it from being returned
  703.             
  704.         // In OpenDoc the 'QUIT' event means CloseDocument.
  705.         
  706.         RealShell* self = (RealShell*)refCon;
  707.         ODDocument* document = kODNULL;
  708.         while ((document = ODGetFirstOpenDocument(ev, session)) != kODNULL)
  709.         {
  710.             if (!self->CloseDocument(document, yesNoAsk))
  711.                 THROW(userCanceledErr);
  712.         }
  713.         session->GetDispatcher(ev)->Exit(ev);
  714.     CATCH_ALL
  715.         error = ErrorCode();
  716.     ENDTRY
  717.  
  718.     return error;
  719. }    // HandleQuitEvent()
  720.  
  721.  
  722. ////////////////////////////////////////////////////////////////////////////////
  723. //
  724. //        HandleLaunchFailedEvent
  725. //
  726. ////////////////////////////////////////////////////////////////////////////////
  727.  
  728. pascal ODError RealShell::HandleLaunchFailedEvent(    ODPart* part,
  729.                                         ODAppleEvent* message,
  730.                                         ODAppleEvent* reply,
  731.                                         long refCon)
  732. {
  733.     ODUnused(part);
  734.     ODUnused(reply);
  735.     
  736.     long launchErr;
  737.     ProcessSerialNumber psn;
  738.     Str255 appName, libName;
  739.     AppleEvent realMessage;
  740.  
  741.     THROW_IF_ERROR(ODDescToAEDesc(message, &realMessage));
  742.     
  743.     //<eeh> any chance this can throw???
  744.     GetLaunchFailedParams(&realMessage, launchErr,&psn,appName,libName);
  745.     ODDisposeAppleEvent(&realMessage);
  746.  
  747.     RealShell *shell = (RealShell*)refCon;
  748.     shell->LaunchFailed(launchErr,psn,appName,libName);
  749.     return noErr;
  750. }
  751.  
  752.  
  753. void
  754. RealShell::LaunchFailed( ODSLong launchErr, const ProcessSerialNumber &psn,
  755.                          Str255 appName, Str255 libName )
  756. {
  757.     if( psn.lowLongOfPSN != kNoProcess ) {
  758.         Boolean result;
  759.         if( SameProcess(&psn,&fLastNewDocPSN,&result) == noErr && result != kODFalse ) {
  760.             // This is a new document we just created & launched; better delete it.
  761.             OSErr err= FSpDelete(&fLastNewDocSpec);
  762.             if( err )
  763.                 WARN("Error %d trying to delete new document",err);
  764.             fLastNewDocPSN.lowLongOfPSN = kNoProcess;
  765.             fLastNewDocSpec.name[0] = '\0';
  766.         }
  767.     }
  768.     
  769.     this->ExceptionAlert(launchErr,kODNULL);
  770. }
  771.  
  772. ////////////////////////////////////////////////////////////////////////////////
  773. //
  774. //        • HandleDocSizeChangeInteraction
  775. //
  776. ////////////////////////////////////////////////////////////////////////////////
  777.  
  778. pascal ODError RealShell::HandleDocSizeChangeInteraction( ODPart* thePart,
  779.                 ODAppleEvent* message, ODAppleEvent* reply, ODSLong handlerRefcon )
  780. {
  781.     // if we get this event, we're being relaunched with what's known to
  782.     // be less memory than the document wants ONLY FOR THE PURPOSE OF GIVING
  783.     // the user a chance to lower the amount wanted.  So put up a dialog here,
  784.     // set a flag so the shell will quit asap after we return, and then send
  785.     // an event to the system process (which should be the source of this
  786.     // event) telling it whether the user wants to change the amount of memory
  787.     // allocated (and relauch) or simply cancel the whole thing.
  788.  
  789.     // $$$$$ eeh - needs minimal error handling (there's really nothing to be
  790.     // done but fail.)
  791.  
  792.     RealShell*        self        = (RealShell*)handlerRefcon;
  793.     Environment*    ev            = self->fEV;
  794.     
  795.     AppleEvent realMessage;
  796.     THROW_IF_ERROR( ODDescToAEDesc(message, &realMessage));
  797.     FSSpec docSpec;
  798.     long ignore1;
  799.     unsigned long ignore2;
  800.     
  801.     OSErr err    = noErr;
  802.     
  803.     err = AEGetParamPtr( &realMessage, 'docs', typeFSS, 
  804.                 &ignore2, (Ptr)&docSpec, sizeof(docSpec), &ignore1);
  805.  
  806.     ODBoolean changeMade = self->ChangeDocSize(&docSpec, kODFalse, kODFalse);
  807.                                                         // Lower size.
  808.     ODError changeError = noErr; 
  809.                                                           
  810.     if ( changeMade == kODTrue )
  811.         changeError =  self->CloseAndReopenDoc(&docSpec);
  812.     else
  813.         // No further changes needed, so make this process go away.
  814.         self->GetSession()->GetDispatcher(ev)->Exit(ev);
  815.  
  816.     return changeError;
  817. }
  818.  
  819. ////////////////////////////////////////////////////////////////////////////////
  820. //
  821. //        • CloseAndReopenDoc
  822. //
  823. //     Method to close and reopen a document in one atomic action. Sends an Apple 
  824. //     event to the System process that will cause the current document to be closed
  825. //     and reopened.
  826. //
  827. ////////////////////////////////////////////////////////////////////////////////
  828. ODError RealShell::CloseAndReopenDoc(FSSpec* docFSSpec)
  829. {
  830.     AppleEvent newEvent;
  831.     AEAddressDesc targetAddress;
  832.     ODBoolean sysProcFound = kODFalse;
  833.  
  834.     ////////////////
  835.     // Code to get psn of sys proc
  836.     ////////////////
  837.     ProcessSerialNumber    iteratorPSN; 
  838.     ProcessInfoRec        procInfo;
  839.     FSSpec                procSpec;
  840.     OSErr                error = noErr;
  841.     OSErr                err = noErr;
  842.     OSErr                 err1    = noErr;
  843.  
  844.     // Needed to get first process from Process Mgr.
  845.     iteratorPSN.highLongOfPSN = 0;
  846.     iteratorPSN.lowLongOfPSN = kNoProcess;
  847.  
  848.     procInfo.processInfoLength = sizeof(procInfo);
  849.     procInfo.processName = NULL;
  850.     procInfo.processAppSpec = &procSpec;
  851.  
  852.     while (error != procNotFound)
  853.     {
  854.         error = GetNextProcess(&iteratorPSN);
  855.         if (!error)
  856.             error = GetProcessInformation(&iteratorPSN, &procInfo);
  857.         if (!error)
  858.         {
  859.             if (procInfo.processSignature == kODShellSignature &&
  860.                 procInfo.processType == 'APPL')
  861.             {
  862.                 sysProcFound = kODTrue;
  863.                 break;
  864.             }
  865.         }
  866.     }
  867.     
  868.     if( sysProcFound == kODTrue )
  869.     {
  870.         ////////////////
  871.         // Create and send CloseReopen event to system proc.
  872.         ////////////////
  873.         err = AECreateDesc(typeProcessSerialNumber, (Ptr)&iteratorPSN, sizeof(iteratorPSN),
  874.                                     &targetAddress);
  875.  
  876.         err = AECreateAppleEvent( kODShellSignature, kODReopenDocEventID,
  877.                 &targetAddress, kAutoGenerateReturnID, kAnyTransactionID,
  878.                 &newEvent );
  879.  
  880.         if( err == noErr )
  881.         {
  882.             err1 = AEPutParamPtr( &newEvent, keyDirectObject, typeFSS, docFSSpec, 
  883.                     sizeof(FSSpec) );
  884.  
  885.             ProcessSerialNumber    psn;
  886.             (void)GetCurrentProcess( &psn );
  887.             err1 = AEPutParamPtr( &newEvent, 'duhh', typeProcessSerialNumber, &psn, 
  888.                     sizeof(psn) );
  889.  
  890.             if( err == noErr && err1 == noErr )
  891.                 err = AESend( &newEvent, NULL, kAENoReply, kAEHighPriority,
  892.                                kAEDefaultTimeout, NULL, NULL );
  893.         }
  894.     }
  895.     else
  896.         return kODErrNotImplemented;
  897.     
  898.     return err;
  899. }
  900.  
  901. ////////////////////////////////////////////////////////////////////////////////
  902. //
  903. //        • ChangeDocSize
  904. //
  905. //    Presents the user with controls to change the size of document process heap.
  906. //    If the input parameter increaseSize is true, then the user will be unable to
  907. //    decrease the size of the from its current size. If it is false, then the 
  908. //    user can only lower the size.
  909. //
  910. //    dh - Note, this method was created to be used to control changing the size of
  911. //    a document under low memory conditions. It does not support setting the document
  912. //    to anything other than higher or lower than its current value. To do that, use
  913. //    the Document Info controls.
  914. //
  915. ////////////////////////////////////////////////////////////////////////////////
  916.  
  917. ODBoolean RealShell::ChangeDocSize(FSSpec* theFSSpec, ODBoolean increaseSize, ODBoolean fatalLowMem)
  918. {
  919.     short          itemHit = kCancelButton;
  920.     Handle        itemHandle = kODNULL;
  921.     short        itemType;
  922.     Boolean        keepRuning = false;
  923.     Rect        scratchRect;
  924.     ODBoolean    userChangedSize = kODFalse;
  925.     StringHandle        tempString = kODNULL;
  926.     short item = 0;
  927.     OSErr err = noErr;
  928.     
  929.     CUsingLibraryResources duh;
  930.     
  931.     // Put the real SIZE resources back.
  932.  
  933.     short theCurResFile = CurResFile();
  934.     short docResFile = FSpOpenResFile(theFSSpec,fsRdWrPerm);
  935.     
  936.     if (docResFile != -1)
  937.     {
  938.         err =  ReplaceResourceWithNewType( kODTempSizeRsrcType, kSIZERsrcType, 0 );
  939.         err =  ReplaceResourceWithNewType( kODTempSizeRsrcType, kSIZERsrcType, 1 );
  940.         CloseResFile( docResFile );    
  941.         UseResFile(theCurResFile);
  942.     }
  943.     PlatformFile* docFile = new PlatformFile();
  944.     docFile->Specify((ODFileSpec*)theFSSpec);
  945.         
  946.     // dh - Deactivate all front windows. Could be multiple front windows because of floating windows.
  947.     // If this is not a fatal low-memory situation, we can use OpenDoc API to do this. Otherwise,
  948.     // serious hacks ensue. These hacks cause problems with the process menu and the About This Mac
  949.     // window, but since the process is going away, it shouldn't be noticable to the user.
  950.  
  951.     CStackPtrList       winList;
  952.     WindowListIterator theWinIter;
  953.     WindowPtr theWin = theWinIter.First();
  954.  
  955.     if( theWin != NULL )
  956.     {
  957.         do
  958.         {
  959.             if( GetWindowHilite(theWin) )
  960.             {
  961.                 HiliteWindow( theWin, false );
  962.                 winList.Add( theWin );
  963.             }
  964.             theWin = theWinIter.Next();
  965.         } while( theWin != NULL );
  966.     }
  967.  
  968.     InitCursor();
  969.     // If we are decreasing the size, this means that we are servicing an event from the
  970.     // system process that responds to a document that has a size that is too high to
  971.     // open.
  972.     if( increaseSize == kODFalse )
  973.     {
  974.         // First check to see if the doc is read-only. If so, cannot change size, so
  975.         // inform the user of other options to open document.
  976.         PlatformFile thefile;
  977.         thefile.Specify( theFSSpec );
  978.         if( thefile.IsLocked() )
  979.             item = CautionAlert( kSHLphDocSizeChangeRO, kODNULL );
  980.         else
  981.             item = CautionAlert( kSHLphDocSizeChange, kODNULL );
  982.     }
  983.     // Otherwise, free app heap space has gotten too low and the user wants to increase
  984.     // the size of the document.
  985.     else
  986.     {
  987.         if( fatalLowMem )
  988.             item = CautionAlert( kSHLphAppSpaceIsLowFatal, kODNULL);
  989.         else
  990.             item = CautionAlert( kSHLphAppSpaceIsLow, kODNULL );
  991.     }
  992.     if( ( increaseSize == kODFalse && item == kDecreaseMemBtn ) || ( increaseSize == kODTrue && item == kOKButton ) )
  993.     {
  994.         DialogPtr    dialog = GetNewDialog (kSHLphAppSpaceIsLowDlg, nil, (WindowPtr) -1);
  995.         if (dialog)
  996.         {        
  997.  
  998.             ODULong curPreferredSize = DHGetDocumentPreferredHeapSize(docFile);
  999.             if( curPreferredSize == 0 )
  1000.                 curPreferredSize = DHGetPreferredSizeInSIZE(docFile, kDefaultDocSizeRes);
  1001.             gSize = curPreferredSize*1024;
  1002.             gOrigDocSize = gSize;
  1003.  
  1004.             DoDialogSetup(dialog, docFile);
  1005.             if( increaseSize == kODTrue )
  1006.                 tempString = GetString(kSHLIncreaseSizeSTR);
  1007.             else
  1008.                 tempString = GetString(kSHLDecreaseSizeSTR);
  1009.             HLock( (Handle)tempString );
  1010.             ParamText(*tempString, kODNULL, kODNULL, kODNULL);
  1011.             DisposeHandle( (Handle)tempString );
  1012.             
  1013.             do
  1014.             {
  1015.                 ModalDialog(NULL, &itemHit);
  1016.                 GetDialogItem(dialog, itemHit, &itemType, &itemHandle, &scratchRect);
  1017.                 keepRuning = DoDialogHits(dialog, itemHit,increaseSize,fatalLowMem);
  1018.             } while ((itemHit != kOKButton) && (itemHit != kCancelButton));
  1019.  
  1020.             if( itemHit == kOKButton )
  1021.             {
  1022.                 if (gSize != curPreferredSize )
  1023.                 {
  1024.                     DHSetDocumentPreferredHeapSize(docFile, gSize/1024);
  1025.                     userChangedSize = kODTrue;
  1026.                 }
  1027.             }
  1028.             
  1029.             DisposeDialog(dialog);
  1030.             delete docFile;
  1031.         }
  1032.     }
  1033.  
  1034.     // Now activate the windows again.
  1035.     int count = winList.GetNumListItems();
  1036.         
  1037.     if( count > 0 )
  1038.     {
  1039.         theWin = (WindowPtr)winList.First();
  1040.         do
  1041.         {
  1042.             HiliteWindow( theWin, true );
  1043.             theWin = (WindowPtr)winList.Next();
  1044.         } while( theWin != kODNULL );
  1045.     }
  1046.  
  1047.     return userChangedSize;
  1048. }
  1049.  
  1050. ////////////////////////////////////////////////////////////////////////////////
  1051. //
  1052. //        HandleODActivateEvent
  1053. //
  1054. ////////////////////////////////////////////////////////////////////////////////
  1055.  
  1056. pascal ODError RealShell::HandleODActivate( ODPart* thePart, ODAppleEvent* message,
  1057.         ODAppleEvent* reply, ODSLong handlerRefcon )
  1058. {
  1059.     ODUnused(thePart);
  1060.     ODUnused(reply);
  1061.     
  1062.     ODError result = noErr;
  1063.  
  1064.     RealShell*    self = (RealShell*)handlerRefcon;
  1065.     
  1066.     ODFileSpec    fileSpec;
  1067.     AppleEvent    realMessage;
  1068.     DescType    unused1;
  1069.     Size        unused2;
  1070.     ODBoolean    wasPrintEvent = kODFalse;
  1071.     ODBoolean    notAlreadyOpen = kODFalse;
  1072.     boolean        quitAfterPrint = kODFalse;
  1073.     TempODDraft draftToBringForward = kODNULL;
  1074.  
  1075.     realMessage.dataHandle = NULL;
  1076.     TRY
  1077.         THROW_IF_ERROR(ODDescToAEDesc(message, &realMessage));
  1078.         THROW_IF_ERROR(AEGetParamPtr(&realMessage, keyDirectObject, typeFSS, 
  1079.                 &unused1, (Ptr)&fileSpec, sizeof(fileSpec), &unused2));
  1080.         DescType spawningEventID;
  1081.         OSErr err = AEGetParamPtr(&realMessage, keyODActivateEventCause,
  1082.                 typeType,  &unused1, (Ptr)&spawningEventID,
  1083.                 sizeof(spawningEventID), &unused2 );
  1084.         if ( err == noErr )
  1085.             wasPrintEvent = spawningEventID == kAEPrintDocuments;
  1086.         // else drop the error: id not present is ok.
  1087.  
  1088.         err = AEGetParamPtr( &realMessage, keyODRefnumFromResource,
  1089.                 typeBoolean,  &unused1, (Ptr)&quitAfterPrint,
  1090.                 sizeof(quitAfterPrint), &unused2 );
  1091.         if ( err != noErr )
  1092.             quitAfterPrint = kODFalse;
  1093.  
  1094.     CATCH_ALL
  1095.         result = ErrorCode();
  1096.     ENDTRY
  1097.     ODDisposeAppleEvent(&realMessage);
  1098.  
  1099.     Environment* ev = self->fEV;
  1100.     ODSession* session = self->GetSession();
  1101.  
  1102.     if ( result == noErr )
  1103.     {
  1104.         ODULong refNumCount, i;
  1105.         ODSShort* refNums = kODNULL;
  1106.         GetLocalPaths(&fileSpec, kDataFork, &refNumCount, &refNums);
  1107.     
  1108.         if (refNumCount != 0)
  1109.         {
  1110.             for ( i=0; i<refNumCount; ++i)
  1111.             {
  1112.                 ODDocument* doc = ODGetOpenDocumentFromRefNum(ev,
  1113.                         session, refNums[i]);
  1114.                 if ( doc != kODNULL )
  1115.                 {
  1116.                     draftToBringForward = ODGetTempDraftFromOpenDocument( ev,
  1117.                             session, doc );
  1118.                             
  1119.                     if (draftToBringForward)
  1120.                         draftToBringForward->Acquire(ev); // balance destructor of TempRef
  1121.                     else
  1122.                         draftToBringForward = 
  1123.                             doc->AcquireDraft(ev,kODDPReadOnly,0,kODNULL,kODPosTop,kODFalse);
  1124.                             
  1125.                     break;        // exit for loop
  1126.                 }
  1127.             }
  1128.         
  1129.             if (refNums)
  1130.                 DisposePtr((Ptr)refNums);
  1131.         }
  1132.         else        // *if* this process is supposed to handle this event at
  1133.         {            // all, the ODActivate must have come because of a resource
  1134.                     // fork.
  1135.             short resRefNum = CurResFile();
  1136.             if ( refNums != kODNULL )
  1137.             {
  1138.                 DisposePtr( (Ptr)refNums );
  1139.                 refNums = kODNULL;
  1140.             }
  1141.             GetLocalPaths( &fileSpec, kResourceFork, &refNumCount, &refNums );
  1142.             for ( i=0; i<refNumCount; ++i )
  1143.             {
  1144.                 if ( refNums[i] == resRefNum )    // it belongs in this process
  1145.                 {
  1146.                     TempPlatformFile file = new PlatformFile;
  1147.                     file->Specify( &fileSpec );
  1148.                     draftToBringForward = ODOpenFileDocument( ev, session, file,
  1149.                         kODDPSharedWrite );
  1150. WARN("When does this happen?????");
  1151.                     self->InstallShellPlugIns(draftToBringForward);
  1152.                     notAlreadyOpen = kODTrue;
  1153.                     break;
  1154.                 }
  1155.             }
  1156.             if( refNums != kODNULL )
  1157.                 DisposePtr( (Ptr)refNums );
  1158.         }
  1159.     }
  1160.     
  1161.     if ( draftToBringForward != kODNULL )
  1162.     {
  1163.         ProcessSerialNumber psn;
  1164.         GetCurrentProcess(&psn);
  1165.         SetFrontProcess(&psn);
  1166. WARN("ODOpenDraft called.");
  1167.         ODOpenDraft( ev, session, draftToBringForward );
  1168.         if ( notAlreadyOpen )
  1169.         {
  1170.             // the plugin may have patched these....
  1171.             self->fDispatcher = session->GetDispatcher(ev);
  1172.             self->fWindowState = session->GetWindowState(ev);
  1173.         }
  1174.         if ( wasPrintEvent )
  1175.         {
  1176.             self->FakePrintMenuEvent();
  1177.             if ( quitAfterPrint )
  1178.             {
  1179.                 // need to release draft's refcount *before* calling
  1180.                 // ODCloseDocument (or check with Tantek to see if
  1181.                 // assertion in ODCloseDocument can be removed.
  1182.                 ODDocument* doc = draftToBringForward->GetDocument(ev);
  1183.                 draftToBringForward->Release(ev);
  1184.                 draftToBringForward = kODNULL;    // prevent another release by the TempRef
  1185.                 ODBoolean wasLastDoc = ODCloseDocument( ev, session, doc );
  1186.                 WASSERT( !wasLastDoc ); 
  1187.             }
  1188.         }
  1189.     }
  1190.  
  1191.     return result;        // usually should be eventNotHandled?
  1192. }    // HandleODActivate
  1193.  
  1194.  
  1195. ////////////////////////////////////////////////////////////////////////////////
  1196. //
  1197. //        CoerceToFSSpec
  1198. //
  1199. ////////////////////////////////////////////////////////////////////////////////
  1200.  
  1201.  
  1202. pascal ODError RealShell::CoerceToFSSpec( ODPart* thePart, ODDesc* theAEDesc,
  1203.         DescType toType, ODSLong handlerRefCon, ODDesc* result )
  1204. {
  1205.     ODUnused(thePart);
  1206.     RealShell*    self = (RealShell*)handlerRefCon;
  1207.  
  1208.     if (self->fAlreadyInCoercion)
  1209.         return errAECoercionFail;
  1210.     else
  1211.         self->fAlreadyInCoercion = kODTrue;
  1212.     ODError    error = noErr;
  1213.  
  1214.     TRY
  1215.         TempAEDescStruct    realInDesc;
  1216.         THROW_IF_ERROR( ODDescToAEDesc(theAEDesc, &realInDesc));
  1217.         if (realInDesc.descriptorType == typeAlias)
  1218.         {
  1219.             // use the built-in coercion first
  1220.             TempAEDescStruct tmpResult;
  1221.             error = AECoerceDesc( &realInDesc, toType, &tmpResult );
  1222.     
  1223.             if ( error == noErr )
  1224.                 THROW_IF_ERROR( AEDescToODDesc( &tmpResult, result ));
  1225.         }
  1226.  
  1227.     CATCH_ALL
  1228.         error = ErrorCode();
  1229.     ENDTRY
  1230.  
  1231.     self->fAlreadyInCoercion = kODFalse;
  1232.     return error;
  1233. }    // CoerceToFSSpec()
  1234.  
  1235. //----------------------------------------------------------------------------------------
  1236. // RealShell::SetAEError 
  1237. //----------------------------------------------------------------------------------------
  1238.  
  1239. void RealShell::SetAEError(ODError error)
  1240. {
  1241.     fErrorFromOpenEvents = error;
  1242. }
  1243.  
  1244. //----------------------------------------------------------------------------------------
  1245. // RealShell::GetAEError 
  1246. //----------------------------------------------------------------------------------------
  1247.  
  1248. ODError RealShell::GetAEError()
  1249. {
  1250.     return fErrorFromOpenEvents;
  1251. }
  1252.  
  1253. //==============================================================================
  1254. // Functions
  1255. //==============================================================================
  1256.  
  1257. //------------------------------------------------------------------------------
  1258. // HandleGetAETE
  1259. //------------------------------------------------------------------------------
  1260.  
  1261.  
  1262. pascal ODError HandleGetAETE(ODPart*        thePart,
  1263.                 ODAppleEvent*    theAppleEvent,
  1264.                 ODAppleEvent*    reply,
  1265.                 ODSLong    handlerRefcon)
  1266. {
  1267. ODUnused(thePart);
  1268. ODUnused(handlerRefcon);    
  1269.  
  1270.     AEDesc        theAETE = NULL_DESCRIPTOR_DEFINITION;
  1271.     DescType    returnedType;
  1272.     ODSize        actualSize;
  1273.     ODSLong        languageCode;
  1274.     ODError        result;
  1275.     ODError        error = noErr;
  1276.     
  1277.     AppleEvent realMessage, realReply;
  1278.     realMessage.dataHandle = realReply.dataHandle = NULL;
  1279.  
  1280.     TRY
  1281.         THROW_IF_ERROR( ODDescToAEDesc(theAppleEvent, &realMessage));
  1282.         THROW_IF_ERROR( ODDescToAEDesc(reply, &realReply));
  1283.  
  1284.         result = AEGetParamPtr(&realMessage, keyDirectObject, typeLongInteger,
  1285.                                &returnedType, (Ptr)&languageCode, sizeof(languageCode),
  1286.                                (Size *)&actualSize);
  1287.         ODDisposeAppleEvent(&realMessage);
  1288.         THROW_IF_ERROR(result);
  1289.         
  1290.         TRY
  1291.             CUsingLibraryResources    ref;
  1292.             
  1293.             theAETE.dataHandle = Get1Resource(typeAETE, (short)languageCode);
  1294.             if (theAETE.dataHandle)
  1295.             {
  1296.                 theAETE.descriptorType = typeAETE;
  1297.                 result = AEPutParamDesc(&realReply, keyAEResult, &theAETE);
  1298.                 ReleaseResource(theAETE.dataHandle);
  1299.                 THROW_IF_ERROR(result);
  1300.             }
  1301.         CATCH_ALL
  1302.             error = ErrorCode();
  1303.         ENDTRY
  1304.                         
  1305.         THROW_IF_ERROR(error);
  1306.         
  1307.         THROW_IF_ERROR(AEDescToODDesc(&realReply, reply));
  1308.     CATCH_ALL
  1309.         error = ErrorCode();
  1310.     ENDTRY
  1311.     AEDisposeDesc(&realReply);
  1312.  
  1313.     return error;
  1314. }    // HandleGetAETE()
  1315.  
  1316.  
  1317. //------------------------------------------------------------------------------
  1318. // GetFileFromNULL
  1319. //------------------------------------------------------------------------------
  1320.  
  1321. pascal ODError GetFileFromNULL(    ODPart*                part,
  1322.                                 DescType            desiredClass,
  1323.                                 ODOSLToken*            container,
  1324.                                 DescType            containerClass,
  1325.                                 DescType            form,
  1326.                                 ODDesc*                selectionData,
  1327.                                 ODOSLToken*            value,
  1328.                                 ODSLong                refCon)
  1329. {
  1330.     Environment*            ev = somGetGlobalEnvironment();
  1331.     ODSession*                session = (ODSession*)refCon;
  1332.     ODNameResolver*            resolver = session->GetNameResolver(ev);
  1333.     ODError                    error = noErr;
  1334.     AEDesc                    aeAlias, tmp;
  1335.     char                    state;
  1336.  
  1337.     TRY
  1338.         // get the selectionData and coerce it into an fsspec
  1339.         THROW_IF_ERROR(ODDescToAEDesc(selectionData, &tmp));
  1340.         TempAEDesc tmpDesc(&tmp);
  1341.         state = HGetState(tmp.dataHandle);
  1342.         HLock(tmp.dataHandle);
  1343.         THROW_IF_ERROR(NewAliasMinimalFromFullPath(GetHandleSize(tmp.dataHandle),
  1344.                 *tmp.dataHandle, "\p", "\p",
  1345.                 (AliasHandle*)&aeAlias.dataHandle ));
  1346.         HSetState(tmp.dataHandle, state);
  1347.         aeAlias.descriptorType = typeAlias;
  1348.         TempAEDesc tmpDesc2(&aeAlias);
  1349.         UpdateUserToken(ev, resolver, value, &aeAlias);
  1350.     CATCH_ALL
  1351.         error = ErrorCode();
  1352.     ENDTRY
  1353.  
  1354.     return error;
  1355. }    //    GetFileFromNULL
  1356.  
  1357. //------------------------------------------------------------------------------
  1358. // HandleClone
  1359. //------------------------------------------------------------------------------
  1360.  
  1361. #ifdef TO_BE_DELETED
  1362. pascal ODError HandleClone( ODPart* thePart, ODAppleEvent* theAppleEvent,
  1363.         ODAppleEvent* reply, ODSLong handlerRefcon )
  1364. {
  1365.     ODUnused(thePart);
  1366.  
  1367.     ODError    error = noErr;
  1368.  
  1369.     AppleEvent realMessage, realReply;
  1370.     THROW_IF_ERROR( ODDescToAEDesc(theAppleEvent, &realMessage));
  1371.     THROW_IF_ERROR( ODDescToAEDesc(reply, &realReply));
  1372.  
  1373.     TRY
  1374.  
  1375.         ShellEventHandler* handlerObj = GetHandlerFromAEVT( &realMessage,
  1376.                 (RealShell*)handlerRefcon );
  1377.     
  1378.         AEDesc cloneLocation;
  1379.         THROW_IF_ERROR( AEGetParamDesc( &realMessage, keyAEInsertHere, 
  1380.                 typeInsertionLoc, &cloneLocation ) );
  1381.     
  1382.         AEDesc replyDp;
  1383.         handlerObj->Clone( &cloneLocation, &replyDp );
  1384.         delete handlerObj;
  1385.     
  1386.         THROW_IF_ERROR( AEPutParamDesc( &realReply, keyDirectObject, &replyDp ) );
  1387.  
  1388.     CATCH_ALL
  1389.         error = ErrorCode();
  1390.     ENDTRY
  1391.  
  1392.     return error;
  1393. }    // HandleClone()
  1394. #endif /* TO_BE_DELETED */
  1395.  
  1396. //------------------------------------------------------------------------------
  1397. // HandleClose
  1398. //------------------------------------------------------------------------------
  1399.  
  1400. pascal ODError HandleClose( ODPart* thePart, ODAppleEvent* message,
  1401.         ODAppleEvent* reply, ODSLong handlerRefcon )
  1402. {
  1403.     ODUnused(thePart);
  1404.     ODUnused(reply);
  1405.  
  1406.     AEDesc theFile;
  1407.     ODError    error = noErr;
  1408.  
  1409.     AppleEvent realMessage, realReply;
  1410.     // can't use TempAEDescs for these because they don't call
  1411.     // ODDisposeAppleEvent
  1412.     realMessage.dataHandle = realReply.dataHandle = NULL;
  1413.  
  1414.     TRY
  1415.         THROW_IF_ERROR( ODDescToAEDesc(message, &realMessage));
  1416.         THROW_IF_ERROR( ODDescToAEDesc(reply, &realReply));
  1417.         OSErr err = AEGetParamDesc(&realMessage, keyAEFile, typeFSS, &theFile);
  1418.         TempAEDesc tmpDesc(&theFile);
  1419.         ThrowIfNotAbsent(err);
  1420.     
  1421.         DescType saveOptions = kAEAsk, typeFound;
  1422.         Size actualSize;
  1423.         err = AEGetParamPtr(&realMessage, keyAESaveOptions, typeEnumeration,
  1424.                 &typeFound, (Ptr)&saveOptions, sizeof(saveOptions), &actualSize);
  1425.         ThrowIfNotAbsent(err);
  1426.     
  1427.         ShellEventHandler* handlerObj = GetHandlerFromAEVT(&realMessage,
  1428.                 (RealShell*)handlerRefcon);
  1429.         handlerObj->Close(&theFile, saveOptions);
  1430.         delete handlerObj;
  1431.  
  1432.     CATCH_ALL
  1433.         error = ErrorCode();
  1434.     ENDTRY
  1435.  
  1436.     ODDisposeAppleEvent(&realMessage);
  1437.     ODDisposeAppleEvent(&realReply);
  1438.     return error;
  1439. }
  1440.  
  1441. //------------------------------------------------------------------------------
  1442. // HandleCountEl
  1443. //------------------------------------------------------------------------------
  1444.  
  1445. #ifdef TO_BE_DELETED
  1446. pascal ODError HandleCountEl(ODPart* thePart, ODAppleEvent* message, ODAppleEvent* reply,
  1447.         ODSLong handlerRefcon)
  1448. {
  1449.     ODUnused(thePart);
  1450.  
  1451.     ODError    error = noErr;
  1452.  
  1453.     AppleEvent realMessage, realReply;
  1454.     THROW_IF_ERROR( ODDescToAEDesc(message, &realMessage));
  1455.     THROW_IF_ERROR( ODDescToAEDesc(reply, &realReply));
  1456.  
  1457.     TRY
  1458.  
  1459.         ShellEventHandler* handlerObj = GetHandlerFromAEVT(&realMessage,
  1460.                 (RealShell*)handlerRefcon);
  1461.     
  1462.         DescType elemClass, typeFound;
  1463.         Size actualSize;
  1464.         THROW_IF_ERROR(AEGetParamPtr(&realMessage, keyAEObjectClass, typeType,
  1465.                 &typeFound, (Ptr)&elemClass, sizeof(elemClass), &actualSize));
  1466.     
  1467.         AEDesc replyDp;
  1468.         handlerObj->CountElements(elemClass, &replyDp);
  1469.         delete handlerObj;
  1470.     
  1471.         THROW_IF_ERROR(AEPutParamDesc(&realReply, keyDirectObject, &replyDp));
  1472.  
  1473.     CATCH_ALL
  1474.         error = ErrorCode();
  1475.     ENDTRY
  1476.  
  1477.     return error;
  1478. }
  1479. #endif /* TO_BE_DELETED */
  1480.  
  1481. //------------------------------------------------------------------------------
  1482. // HandleMake
  1483. //------------------------------------------------------------------------------
  1484.  
  1485. #ifdef TO_BE_DELETED
  1486. pascal ODError HandleMake(ODPart* thePart, ODAppleEvent* message,
  1487.         ODAppleEvent* reply, ODSLong handlerRefcon)
  1488. {
  1489.     ODUnused(thePart);
  1490.     ODUnused(handlerRefcon);
  1491.     ODUnused(reply);
  1492.  
  1493.     DescType newObjClass, typeFound;
  1494.     Size actualSize;
  1495.     AEDesc insertHere, newObjectName;
  1496.     OSErr err;
  1497.     ODError    error = noErr;
  1498.  
  1499.     AppleEvent realMessage, realReply;
  1500.     THROW_IF_ERROR( ODDescToAEDesc(message, &realMessage));
  1501.     THROW_IF_ERROR( ODDescToAEDesc(reply, &realReply));
  1502.  
  1503.     TRY
  1504.     
  1505.         THROW_IF_ERROR(AEGetParamPtr(&realMessage, keyAEObjectClass, typeType,
  1506.                 &typeFound, (Ptr)&newObjClass, sizeof(newObjClass), &actualSize));
  1507.         THROW_IF_ERROR(AEGetParamDesc(&realMessage, keyAEInsertHere,
  1508.                 typeInsertionLoc, &insertHere));
  1509.         err = AEGetParamDesc(&realMessage, 'type', typeChar, &newObjectName);
  1510.         if (err && (err != errAEDescNotFound))
  1511.             THROW(err);
  1512.     
  1513.         err = AEGetParamDesc(&realMessage, 'subj', typeChar, &newObjectName);
  1514.         if (err && (err != errAEDescNotFound))
  1515.             THROW(err);
  1516.  
  1517.     CATCH_ALL
  1518.         error = ErrorCode();
  1519.     ENDTRY
  1520.  
  1521.     return error;
  1522. }
  1523. #endif /* TO_BE_DELETED */
  1524.  
  1525. //------------------------------------------------------------------------------
  1526. // HandleDelete
  1527. //------------------------------------------------------------------------------
  1528.  
  1529. #ifdef TO_BE_DELETED
  1530. pascal ODError HandleDelete( ODPart* thePart, ODAppleEvent* message,
  1531.         ODAppleEvent* reply, ODSLong handlerRefcon )
  1532. {
  1533.     ODUnused(thePart);
  1534.     ODUnused(reply);
  1535.     ODError error = noErr;
  1536.  
  1537.     AppleEvent realMessage, realReply;
  1538.     THROW_IF_ERROR( ODDescToAEDesc(message, &realMessage));
  1539.     THROW_IF_ERROR( ODDescToAEDesc(reply, &realReply));
  1540.  
  1541.     TRY
  1542.         ShellEventHandler* handlerObj = GetHandlerFromAEVT(&realMessage,
  1543.                 (RealShell*)handlerRefcon);
  1544.         handlerObj->Delete();
  1545.         delete handlerObj;
  1546.  
  1547.     CATCH_ALL
  1548.         error = ErrorCode();
  1549.     ENDTRY
  1550.  
  1551.     return error;
  1552. }
  1553. #endif /* TO_BE_DELETED */
  1554.  
  1555. //------------------------------------------------------------------------------
  1556. // HandleDoExist
  1557. //------------------------------------------------------------------------------
  1558.  
  1559. #ifdef TO_BE_DELETED
  1560. pascal ODError HandleDoExist( ODPart* thePart, ODAppleEvent* message,
  1561.         ODAppleEvent* reply, ODSLong handlerRefcon )
  1562. {
  1563.     ODUnused(thePart);
  1564.     ODUnused(message);
  1565.     ODUnused(reply);
  1566.     ODUnused(handlerRefcon);
  1567.     return errAEEventNotHandled;
  1568. }
  1569. #endif /* TO_BE_DELETED */
  1570.  
  1571. //------------------------------------------------------------------------------
  1572. // HandleGetClsInfo
  1573. //------------------------------------------------------------------------------
  1574.  
  1575. #ifdef TO_BE_DELETED
  1576. pascal ODError HandleGetClsInfo( ODPart* thePart, ODAppleEvent* message,
  1577.         ODAppleEvent* reply, ODSLong handlerRefcon )
  1578. {
  1579.     ODUnused(thePart);
  1580.     ODUnused(message);
  1581.     ODUnused(reply);
  1582.     ODUnused(handlerRefcon);
  1583.     return errAEEventNotHandled;
  1584. }
  1585. #endif /* TO_BE_DELETED */
  1586.  
  1587. //------------------------------------------------------------------------------
  1588. // HandleGetData
  1589. //------------------------------------------------------------------------------
  1590.  
  1591. #ifdef TO_BE_DELETED
  1592. pascal ODError HandleGetData( ODPart* thePart, ODAppleEvent* message,
  1593.         ODAppleEvent* reply, ODSLong handlerRefcon )
  1594. {
  1595.     ODUnused(thePart);
  1596.     ODUnused(handlerRefcon);
  1597.  
  1598.     AEDesc evtDp;
  1599.     AEDesc replyDp;
  1600.     ODError    error = noErr;
  1601.  
  1602.     RealShell* self = (RealShell*)handlerRefcon;
  1603.     Environment* ev = somGetGlobalEnvironment();
  1604.     ODNameResolver* resolver = self->GetSession()->GetNameResolver(ev);
  1605.  
  1606.     AppleEvent realMessage, realReply;
  1607.     THROW_IF_ERROR( ODDescToAEDesc(message, &realMessage));
  1608.     THROW_IF_ERROR( ODDescToAEDesc(reply, &realReply));
  1609.  
  1610. //    ODOSLToken* tmpWrapper = kODNULL;
  1611.     TRY
  1612.  
  1613.         replyDp.dataHandle = NULL;
  1614.         evtDp.dataHandle = NULL;
  1615.     
  1616.         GetDirectParam((RealShell*)handlerRefcon, &realMessage,
  1617.                 &evtDp);
  1618.         ODOSLToken* tmpWrapper = new ODOSLToken();
  1619.         THROW_IF_NULL(tmpWrapper);
  1620.         TempODObject tempObj(tmpWrapper);
  1621.         tmpWrapper->InitODOSLToken(ev);
  1622.         THROW_IF_ERROR( AEDescToODDesc(&evtDp, tmpWrapper ) );
  1623.  
  1624.         if( !resolver->IsODToken(ev, tmpWrapper) )
  1625.             THROW(errAEEventNotHandled);
  1626.         ODDesc* myTokenODDesc;
  1627.         myTokenODDesc = resolver->GetUserToken(ev, tmpWrapper);
  1628.         AEDesc myToken;
  1629.         THROW_IF_ERROR( ODDescToAEDesc(myTokenODDesc, &myToken ));
  1630. //        ODDeleteObject(myTokenODDesc);
  1631.         
  1632.         switch( myToken.descriptorType )
  1633.         {
  1634.             case kShellSelfPropAccessor :
  1635.             case kShellPropAccessor :
  1636.                 ShellPropAccessor* accessorObj =
  1637.                         FIRSTBYTESFROMHANDLE((&myToken)->dataHandle,
  1638.                         ShellPropAccessor*);
  1639.                 accessorObj->GetPropertyData(&replyDp);
  1640.                 delete accessorObj;
  1641.                 break;
  1642.     
  1643.             default :
  1644.                 THROW(errAEEventNotHandled);
  1645.                 break;
  1646.         }
  1647.  
  1648.         THROW_IF_ERROR(AEPutParamDesc(&realReply, keyDirectObject, &replyDp));
  1649.         THROW_IF_ERROR( AEDescToODDesc(&realReply, reply ) );
  1650.         
  1651.         AEDisposeDesc(&evtDp);
  1652.         AEDisposeDesc(&replyDp);
  1653.  
  1654.     CATCH_ALL
  1655.         error = ErrorCode();
  1656.     ENDTRY
  1657.  
  1658. //    ODDeleteObject(tmpWrapper);
  1659.     return error;
  1660. }    // HandleGetData();
  1661. #endif /* TO_BE_DELETED */
  1662.  
  1663.  
  1664. //------------------------------------------------------------------------------
  1665. // HandleGetDataSz
  1666. //------------------------------------------------------------------------------
  1667.  
  1668. #ifdef TO_BE_DELETED
  1669. pascal ODError HandleGetDataSz( ODPart* thePart, ODAppleEvent* message,
  1670.         ODAppleEvent* reply, ODSLong handlerRefcon )
  1671. {
  1672.     ODUnused(thePart);
  1673.     ODUnused(message);
  1674.     ODUnused(reply);
  1675.     ODUnused(handlerRefcon);
  1676.     return errAEEventNotHandled;
  1677. }
  1678. #endif /* TO_BE_DELETED */
  1679.  
  1680. //------------------------------------------------------------------------------
  1681. // HandleGetEvnInfo
  1682. //------------------------------------------------------------------------------
  1683.  
  1684. #ifdef TO_BE_DELETED
  1685. pascal ODError HandleGetEvnInfo( ODPart* thePart, ODAppleEvent* message,
  1686.         ODAppleEvent* reply, ODSLong handlerRefcon )
  1687. {
  1688.     ODUnused(thePart);
  1689.     ODUnused(message);
  1690.     ODUnused(reply);
  1691.     ODUnused(handlerRefcon);
  1692.     return errAEEventNotHandled;
  1693. }
  1694. #endif /* TO_BE_DELETED */
  1695.  
  1696. //------------------------------------------------------------------------------
  1697. // HandleMove
  1698. //------------------------------------------------------------------------------
  1699.  
  1700. #ifdef TO_BE_DELETED
  1701. pascal ODError HandleMove( ODPart* thePart, ODAppleEvent* message,
  1702.         ODAppleEvent* reply, ODSLong handlerRefcon )
  1703. {
  1704.     ODUnused(thePart);
  1705.     ODUnused(message);
  1706.     ODUnused(reply);
  1707.     ODUnused(handlerRefcon);
  1708.     return errAEEventNotHandled;
  1709. }
  1710. #endif /* TO_BE_DELETED */
  1711.  
  1712. //------------------------------------------------------------------------------
  1713. // HandleOpen
  1714. //------------------------------------------------------------------------------
  1715.  
  1716. #ifdef TO_BE_DELETED
  1717. pascal ODError HandleOpen( ODPart* thePart, ODAppleEvent* message,
  1718.         ODAppleEvent* reply, ODSLong handlerRefcon )
  1719. {
  1720.     ODUnused(thePart);
  1721.     ODUnused(message);
  1722.     ODUnused(reply);
  1723.     ODUnused(handlerRefcon);
  1724.     return errAEEventNotHandled;
  1725. }
  1726. #endif /* TO_BE_DELETED */
  1727.  
  1728. //------------------------------------------------------------------------------
  1729. // HandlePrint
  1730. //------------------------------------------------------------------------------
  1731.  
  1732. #ifdef TO_BE_DELETED
  1733. pascal ODError HandlePrint( ODPart* thePart, ODAppleEvent* message,
  1734.         ODAppleEvent* reply, ODSLong handlerRefcon )
  1735. {
  1736.     ODUnused(thePart);
  1737.     ODUnused(message);
  1738.     ODUnused(reply);
  1739.     ODUnused(handlerRefcon);
  1740.     return errAEEventNotHandled;
  1741. }
  1742. #endif /* TO_BE_DELETED */
  1743.  
  1744. //------------------------------------------------------------------------------
  1745. // HandleSave
  1746. //------------------------------------------------------------------------------
  1747.  
  1748. pascal ODError HandleSave( ODPart* thePart, ODAppleEvent* message,
  1749.         ODAppleEvent* reply, ODSLong handlerRefcon )
  1750. {
  1751.     ODUnused(thePart);
  1752.     ODUnused(reply);
  1753.     AEDesc theFile;
  1754.     ODError    error = noErr;
  1755.  
  1756.     AppleEvent realMessage, realReply;
  1757.     realMessage.dataHandle = realReply.dataHandle = NULL;
  1758.  
  1759.     TRY
  1760.         THROW_IF_ERROR( ODDescToAEDesc(message, &realMessage));
  1761.         THROW_IF_ERROR( ODDescToAEDesc(reply, &realReply));
  1762.  
  1763.         OSErr err = AEGetParamDesc(&realMessage, keyAEFile, typeFSS, &theFile);
  1764.         ThrowIfNotAbsent(err);
  1765.     
  1766.     //    keyAEFileType
  1767.     
  1768.         ShellEventHandler* handlerObj = GetHandlerFromAEVT(&realMessage,
  1769.                 (RealShell*)handlerRefcon);
  1770.         handlerObj->Save(&theFile /*,&theFileType*/);
  1771.         delete handlerObj;
  1772.  
  1773.     CATCH_ALL
  1774.         error = ErrorCode();
  1775.     ENDTRY
  1776.  
  1777.     ODDisposeAppleEvent(&realMessage);
  1778.     ODDisposeAppleEvent(&realReply);
  1779.     return error;
  1780. }    // HandleSave()
  1781.  
  1782. //------------------------------------------------------------------------------
  1783. // HandleSetData
  1784. //------------------------------------------------------------------------------
  1785.  
  1786. #ifdef TO_BE_DELETED
  1787. pascal ODError HandleSetData( ODPart* thePart, ODAppleEvent* message,
  1788.         ODAppleEvent* reply, ODSLong handlerRefcon )
  1789. {
  1790.     ODUnused(thePart);
  1791.     ODUnused(reply);
  1792.  
  1793.     AEDesc dataDesc;
  1794.     ODError    error = noErr;
  1795.  
  1796.     RealShell* self = (RealShell*)handlerRefcon;
  1797.     Environment* ev = somGetGlobalEnvironment();
  1798.     ODNameResolver* resolver = self->GetSession()->GetNameResolver(ev);
  1799.  
  1800.     AppleEvent realMessage, realReply;
  1801.     THROW_IF_ERROR( ODDescToAEDesc(message, &realMessage));
  1802. //    THROW_IF_ERROR( ODDescToAEDesc(reply, &realReply));
  1803.  
  1804. //    ODOSLToken* tmpWrapper = kODNULL;
  1805.     TRY
  1806.  
  1807.         dataDesc.dataHandle = NULL;
  1808.         THROW_IF_ERROR(AEGetParamDesc(&realMessage, keyAEData, typeWildCard,
  1809.                 &dataDesc));
  1810.     
  1811.         AEDesc evtDp;
  1812.         GetDirectParam( self, &realMessage, &evtDp );
  1813.         AEDisposeDesc( &realMessage );
  1814.     
  1815.         ODOSLToken* tmpWrapper = new ODOSLToken();
  1816.         THROW_IF_NULL(tmpWrapper);
  1817.         TempODObject tempObj(tmpWrapper);
  1818.         tmpWrapper->InitODOSLToken(ev);
  1819.         THROW_IF_ERROR( AEDescToODDesc(&evtDp, tmpWrapper ) );
  1820.     
  1821.         if( !resolver->IsODToken(ev, tmpWrapper) )
  1822.             THROW(errAEEventNotHandled);
  1823.         ODDesc* myTokenODDesc = resolver->GetUserToken(ev, tmpWrapper);
  1824.         AEDesc myToken;
  1825.         THROW_IF_ERROR( ODDescToAEDesc(myTokenODDesc, &myToken) );
  1826.     
  1827.         switch( myToken.descriptorType )
  1828.         {
  1829.             case kShellSelfPropAccessor :
  1830.             case kShellPropAccessor :
  1831.                 ShellPropAccessor* accessorObj =
  1832.                         FIRSTBYTESFROMHANDLE((&myToken)->dataHandle,
  1833.                         ShellPropAccessor*);
  1834.                 accessorObj->SetPropertyData(&dataDesc);
  1835.                 delete accessorObj;
  1836.                 break;
  1837.             default :
  1838.                 THROW(errAEEventNotHandled);
  1839.                 break;
  1840.         }
  1841.     
  1842.         AEDisposeDesc(&myToken);    
  1843.         AEDisposeDesc(&dataDesc);    
  1844.  
  1845.     CATCH_ALL
  1846.         AEDisposeDesc(&dataDesc);    
  1847.         error = ErrorCode();
  1848.     ENDTRY
  1849.  
  1850. //    ODDeleteObject(tmpWrapper);
  1851.     return error;
  1852. }    // HandleSetData()
  1853. #endif /* TO_BE_DELETED */
  1854.  
  1855.  
  1856. //******************************************************************************
  1857. // Utility functions
  1858. //******************************************************************************
  1859.  
  1860. ShellEventHandler* GetHandlerFromAEVT(AppleEvent* message,
  1861.         RealShell* self)
  1862. {
  1863.     Environment* ev = somGetGlobalEnvironment();
  1864.     ODNameResolver* resolver = self->GetSession()->GetNameResolver(ev);
  1865.  
  1866.     AEDesc evtDp;
  1867.     THROW_IF_ERROR(AEGetParamDesc(message, keyDirectObject, typeWildCard,
  1868.             &evtDp));
  1869.     TempAEDesc tmpdesc(&evtDp);
  1870.  
  1871.     ShellEventHandler* handlerObj;
  1872.     if (evtDp.descriptorType == typeNull)
  1873.     {
  1874.         handlerObj = new ShellEventHandler(typeNull, (ODObject*)self,
  1875.                 (ODSLong)self);
  1876.     }
  1877.     else
  1878.     {
  1879.         ODOSLToken* tmpWrapper = new ODOSLToken();
  1880.         THROW_IF_NULL(tmpWrapper);
  1881.         TempODObject tempObj(tmpWrapper);
  1882.         tmpWrapper->InitODOSLToken(ev);
  1883.         THROW_IF_ERROR( AEDescToODDesc(&evtDp, tmpWrapper ) );
  1884.     
  1885.         if( !resolver->IsODToken(ev, tmpWrapper) )
  1886.             THROW(errAEEventNotHandled);
  1887.         ODDesc* myTokenODDesc;
  1888.         myTokenODDesc = resolver->GetUserToken(ev, tmpWrapper);
  1889.         AEDesc myToken;
  1890.         THROW_IF_ERROR( ODDescToAEDesc(myTokenODDesc, &myToken ));
  1891.  
  1892.         handlerObj = FIRSTBYTESFROMHANDLE(myToken.dataHandle,
  1893.                 ShellEventHandler*);
  1894.         AEDisposeDesc(&myToken);
  1895. //        ODDeleteObject(tmpWrapper);
  1896.     }
  1897.  
  1898. //    AEDisposeDesc(&evtDp);
  1899.     return handlerObj;
  1900. }    // GetHandlerFromAEVT()
  1901.  
  1902.  
  1903. //------------------------------------------------------------------------------
  1904. // GetDirectParam
  1905. //------------------------------------------------------------------------------
  1906.  
  1907. // THIS FUNCTION NEEDS A FIXIN' TO USE THE NEW WAY OF DOING DEFAULT ACCESSORS.
  1908.  
  1909. void GetDirectParam(RealShell* self, AppleEvent* message,
  1910.         AEDesc* evtDp)
  1911. {
  1912.     Environment* ev = somGetGlobalEnvironment();
  1913.     AEDesc localDP;
  1914.     THROW_IF_ERROR(AEGetParamDesc(message, keyDirectObject, typeWildCard,
  1915.             &localDP));
  1916.  
  1917.     ODNameResolver* resolver = self->GetSession()->GetNameResolver(ev);
  1918.  
  1919.     ODOSLToken* tmpWrapper = new ODOSLToken();
  1920.     THROW_IF_NULL(tmpWrapper);
  1921.     TempODObject tempObj(tmpWrapper);
  1922.     tmpWrapper->InitODOSLToken(ev);
  1923.     THROW_IF_ERROR( AEDescToODDesc(&localDP, tmpWrapper ) );
  1924.  
  1925.     ODBoolean istoken = resolver->IsODToken(ev, tmpWrapper) ;
  1926. //    ODDeleteObject(tmpWrapper);
  1927.     if ( istoken )
  1928.     {
  1929.         *evtDp = localDP;
  1930.     }
  1931.     else
  1932.     {
  1933.         WARN("RlShlEv.cpp: GetDirectParam. Found a non-token.  About to throw.");
  1934.         THROW( errAEEventNotHandled );
  1935.     }
  1936. }    // GetDirectParam()
  1937.  
  1938. //•-----------------------------------------------------------------------------
  1939. //•-----------------------------------------------------------------------------
  1940. //• Utility functions for memory size dialog------------------------------------
  1941. //•-----------------------------------------------------------------------------
  1942. //•-----------------------------------------------------------------------------
  1943.  
  1944. //------------------------------------------------------------------------------
  1945. // DoDialogSetup
  1946. //------------------------------------------------------------------------------
  1947.  
  1948. static void    DoDialogSetup( DialogPtr dialog, PlatformFile* docFile)
  1949. {
  1950.     Rect                buttonRect;
  1951.     short                itemType;
  1952.     Handle                itemHandle;
  1953.  
  1954.     // Hard-coded values. I hope it's OK for the localizers, but probably not.
  1955.     //    I tried to make Resorcerer use an ictb, but it was hard to get it to
  1956.     //    work right.
  1957.     long scriptSmallFontSize;
  1958.     scriptSmallFontSize = GetScriptVariable(smSystemScript,
  1959.                                                 smScriptSmallFondSize);
  1960.     dialog->txFont    = HiWord(scriptSmallFontSize);
  1961.     dialog->txSize    = LoWord(scriptSmallFontSize);
  1962.  
  1963.     SetDialogMemorySize(dialog, gSize);
  1964.  
  1965.     SetPort(dialog);
  1966.  
  1967.     // Set the new Document Size in Kbytes
  1968.     SetNumText(dialog, kCurDocHeapPrefSizeFld, gSize/1024);
  1969.     SetNumText(dialog, kNewDocHeapPrefSizeFld, gSize/1024);
  1970.     
  1971.     // Hide text about closing and reopening document when clicking OK.
  1972.     HideDialogItem(dialog, kSaveChangesTxtItem );
  1973.     GetDialogItem(dialog, kOKButton, &itemType, &itemHandle, &buttonRect);
  1974.     HiliteControl((ControlHandle)itemHandle, kControlInactive);    // Dim OK button
  1975.     ODOutlineDefaultButtonDrawProc(dialog, kOKButton);
  1976.  
  1977.     ShowWindow (dialog);
  1978.     HiliteWindow( dialog, true );
  1979.  
  1980.     PlotArrowIcon(dialog, kArrowControl);
  1981.  
  1982.     InitCursor ();
  1983.  
  1984. #ifdef _APPLEGUIDE_READY_
  1985.     DialogSetUpAppleGuide( dialog, kDocHeapAppleGuideButton );
  1986. #endif
  1987. }
  1988.  
  1989. //------------------------------------------------------------------------------
  1990. // DoDialogHits
  1991. //
  1992. //    Returns whether we should keep gRunning.
  1993. //------------------------------------------------------------------------------
  1994.  
  1995. static Boolean DoDialogHits(DialogPtr dialog, short itemHit, ODBoolean increaseSize,
  1996.                             ODBoolean fatalLowMem)
  1997. {
  1998.     Boolean    shouldKeepRunning = true;
  1999.  
  2000.     switch (itemHit)
  2001.     {
  2002.         case kCancelButton :
  2003. //            sz = originalSize; // used to have an OK, Cancel interface.
  2004.         case kOKButton :
  2005.             shouldKeepRunning = false;
  2006.             break;
  2007.         
  2008.         case kArrowBottom :
  2009.         case kArrowTop :
  2010.             DoMemorySettingHits(dialog, itemHit, increaseSize, fatalLowMem);
  2011.             break;
  2012.  
  2013. #ifdef _APPLEGUIDE_READY_
  2014.         case kDocHeapAppleGuideButton:
  2015.             OpenAppleGuide( ODGetIndShort( kODShellGuideSearchIndices,
  2016.                     kODShellGuideStringIndexSize ) );
  2017.             break;
  2018. #endif
  2019.  
  2020.         default: 
  2021.             break;
  2022.     }
  2023.     
  2024.     return shouldKeepRunning;
  2025. }
  2026.  
  2027. //------------------------------------------------------------------------------
  2028. // SetDialogMemorySize
  2029. //------------------------------------------------------------------------------
  2030.  
  2031. static void SetDialogMemorySize (DialogPtr dlog, Size size)
  2032. {
  2033.     long        kilobytes = size / 1024;
  2034.     Str255        text;
  2035.     Rect        itemRect;
  2036.     short        itemType;
  2037.     Handle        itemHandle;
  2038.     
  2039.     GetDialogItem (dlog, kNewDocHeapPrefSizeFld, &itemType, &itemHandle, &itemRect);
  2040.     
  2041.     NumToString (kilobytes, text);
  2042.     SetDialogItemText (itemHandle, text);
  2043. }
  2044.  
  2045. //------------------------------------------------------------------------------
  2046. // MyUserItemProc
  2047. //------------------------------------------------------------------------------
  2048.  
  2049. pascal void MyUserItemProc (DialogPtr dlog, short item)
  2050. {
  2051. /*
  2052.     Rect        itemRect;
  2053.     short        itemType;
  2054.     Handle        itemHandle;
  2055.     
  2056.     GetDialogItem (dlog, item, &itemType, &itemHandle, &itemRect);
  2057.     
  2058.     switch (item) {
  2059.     
  2060.         case kArrowControl :
  2061.         case kArrowTop :
  2062.         case kArrowBottom :
  2063.             PlotArrowIcon(dlog, item);
  2064.             break;
  2065.     
  2066.         case kOKButton : // can be done automatically by Dialog Mgr.
  2067. //            PenNormal ();
  2068. //            PenSize (3, 3);
  2069. //            FrameRoundRect (&itemRect, 16, 16);
  2070.             break;
  2071.     }
  2072. */
  2073. }
  2074.  
  2075. //------------------------------------------------------------------------------
  2076. // DoMemorySettingHits
  2077. //------------------------------------------------------------------------------
  2078.  
  2079.  
  2080. static void DoMemorySettingHits(DialogPtr dialog, short itemHit, ODBoolean increaseSize,
  2081.                                 ODBoolean fatalLowMem)
  2082. {
  2083.     // If parameter increaseSize is true, then do not let doc size go under the original
  2084.     // doc size. If the parameter is false, then do let go over the original size.
  2085.     
  2086.     short            itemType;
  2087.     Handle            itemHandle;
  2088.     Rect            arrowRect;
  2089.     Rect            buttonRect;
  2090.     Point            mousePoint;
  2091.     long            ignore;
  2092.     GrafPtr            savePort;
  2093.     ODULong            tempSize = 0;
  2094.     ODULong            tempSize1 = 0;
  2095.     
  2096.     switch (itemHit)
  2097.     {
  2098.         case kArrowBottom :
  2099.             GetDialogItem(dialog, kArrowBottom, &itemType,
  2100.                             &itemHandle, &arrowRect);
  2101.             PlotArrowIcon(dialog, itemHit);
  2102.             GetPort(&savePort);
  2103.             SetPort(dialog);
  2104.             do
  2105.             {
  2106.                 GetMouse(&mousePoint);
  2107.                 if (PtInRect(mousePoint, &arrowRect))
  2108.                 {
  2109.                     gSize -= kSizeIncrement;
  2110.                     // We want to make sure the user doesn't make the size smaller than:
  2111.                     // A. The minimum size a document could possibly have.
  2112.                     // B. The original size of the document if we are supposed to increase the size.
  2113.                     if (gSize < kDocStubMinHeapSize || (increaseSize && (gSize < gOrigDocSize)))
  2114.                     {
  2115.                         gSize += kSizeIncrement;
  2116.                         HideDialogItem(dialog, kSaveChangesTxtItem );
  2117.                         GetDialogItem(dialog, kOKButton, &itemType, &itemHandle, &buttonRect);
  2118.                         HiliteControl((ControlHandle)itemHandle, kControlInactive);    // Dim OK button
  2119.                         ODOutlineDefaultButtonDrawProc(dialog, kOKButton);
  2120.                     }
  2121.                     else
  2122.                     {
  2123.                         SetDialogMemorySize (dialog, gSize);
  2124.                         if( increaseSize && (gSize <= gOrigDocSize) )
  2125.                         {
  2126.                             HideDialogItem(dialog, kSaveChangesTxtItem );
  2127.                             GetDialogItem(dialog, kOKButton, &itemType, &itemHandle, &buttonRect);
  2128.                             HiliteControl((ControlHandle)itemHandle, kControlInactive);    // Dim OK button
  2129.                             ODOutlineDefaultButtonDrawProc(dialog, kOKButton);
  2130.                         }
  2131.                         else
  2132.                         {
  2133.                             // If the user can make a change
  2134.                             GetDialogItem(dialog, kOKButton, &itemType, &itemHandle, &buttonRect);
  2135.                             HiliteControl((ControlHandle)itemHandle, kControlActive);    // Enable OK button
  2136.                             ODOutlineDefaultButtonDrawProc(dialog, kOKButton);
  2137.                             if( !fatalLowMem )
  2138.                                 ShowDialogItem(dialog, kSaveChangesTxtItem );
  2139.                         }
  2140.                     }
  2141.                     Delay(8, &ignore);
  2142.                 }
  2143.             }
  2144.             while (StillDown());
  2145.             SetPort(savePort);
  2146.             PlotArrowIcon(dialog, kArrowControl);
  2147.             break;
  2148.             
  2149.         case kArrowTop :
  2150.             GetDialogItem(dialog, kArrowTop, &itemType,
  2151.                             &itemHandle, &arrowRect);
  2152.             PlotArrowIcon(dialog, itemHit);
  2153.             GetPort(&savePort);
  2154.             SetPort(dialog);
  2155.             do
  2156.             {
  2157.                 GetMouse(&mousePoint);
  2158.                 if (PtInRect(mousePoint, &arrowRect))
  2159.                 {
  2160.                     gSize += kSizeIncrement;
  2161.                     // We want to make sure the user doesn't make the size bigger than:
  2162.                     // A. The maximum size a document could possibly have.
  2163.                     // B. The original size of the document if we are supposed to decrease the size.
  2164.                     if (gSize > kMaximumSize || (!increaseSize && (gSize > gOrigDocSize)))
  2165.                     {
  2166.                         gSize -= kSizeIncrement;
  2167.                         HideDialogItem(dialog, kSaveChangesTxtItem );
  2168.                         // Disable OK button. How do you do this???
  2169.                         GetDialogItem(dialog, kOKButton, &itemType, &itemHandle, &buttonRect);
  2170.                         HiliteControl((ControlHandle)itemHandle, kControlInactive);    // Dim OK button
  2171.                         ODOutlineDefaultButtonDrawProc(dialog, kOKButton);
  2172.                     }
  2173.                     else
  2174.                     {
  2175.                         SetDialogMemorySize (dialog, gSize);
  2176.                         if( !increaseSize &&  ( gSize >= gOrigDocSize ) )
  2177.                         {
  2178.                             HideDialogItem(dialog, kSaveChangesTxtItem );
  2179.                             GetDialogItem(dialog, kOKButton, &itemType, &itemHandle, &buttonRect);
  2180.                             HiliteControl((ControlHandle)itemHandle, kControlInactive);    // Dim OK button
  2181.                             ODOutlineDefaultButtonDrawProc(dialog, kOKButton);
  2182.                         }
  2183.                         else
  2184.                         {
  2185.                             GetDialogItem(dialog, kOKButton, &itemType, &itemHandle, &buttonRect);
  2186.                             HiliteControl((ControlHandle)itemHandle, kControlActive);    // Enable OK button
  2187.                             ODOutlineDefaultButtonDrawProc(dialog, kOKButton);
  2188.                             if( !fatalLowMem )
  2189.                                 ShowDialogItem(dialog, kSaveChangesTxtItem );
  2190.                         }
  2191.                     }
  2192.                     Delay(8, &ignore);
  2193.                 }
  2194.             }
  2195.             while (StillDown());
  2196.             SetPort(savePort);
  2197.             PlotArrowIcon(dialog, kArrowControl);
  2198.             break;
  2199.     }
  2200. }
  2201.  
  2202. //------------------------------------------------------------------------------
  2203. // PlotArrowIcon
  2204. //------------------------------------------------------------------------------
  2205.  
  2206. static void PlotArrowIcon(DialogPtr dlog, short item)
  2207. {
  2208.     RgnHandle    tempRgn = NewRgn();
  2209.     Handle        icon;
  2210.     Rect        arrowRect;
  2211.     short        itemType;
  2212.     Handle        itemHandle;
  2213.     GrafPtr        savePort;
  2214.  
  2215.     GetPort(&savePort);
  2216.     SetPort(dlog);
  2217.     GetClip(tempRgn);
  2218.     GetDialogItem(dlog, kArrowControl, &itemType, &itemHandle, &arrowRect);
  2219.     ClipRect (&arrowRect);
  2220.     arrowRect.bottom = arrowRect.top + 32;
  2221.     arrowRect.right = arrowRect.left + 32;
  2222.  
  2223.     switch (item)
  2224.     {
  2225.         case kArrowControl:
  2226.             icon = GetResource('ICON', kNormalIconID);
  2227.             break;
  2228.         case kArrowTop:
  2229.             icon = GetResource('ICON', kUpArrowIconID);
  2230.             break;
  2231.         case kArrowBottom:
  2232.             icon = GetResource('ICON', kDownArrowIconID);
  2233.             break;
  2234.     }
  2235.  
  2236.     PlotIcon(&arrowRect, icon);
  2237.  
  2238.     SetClip(tempRgn);
  2239.     DisposeRgn(tempRgn);
  2240.     SetPort(savePort);    
  2241. }
  2242.  
  2243. static void ODOutlineDefaultButtonDrawProc(DialogPtr theDialog, short theItem)
  2244. {
  2245.     // NOTE: this proc only works on buttons whose DITL ID is 1.  theItem
  2246.     // is unused, and so it doesn't matter whether the user item to which
  2247.     // this proc is assigned (via SetDialogItem) has any geographical
  2248.     // relation to the button.
  2249.     
  2250.     ODUnused(theItem);
  2251.     Rect         itemRect;
  2252.     Handle        itemHandle;
  2253.     short        itemKind;
  2254.  
  2255.     WindowPtr    buttonWindow;
  2256.     WindowPtr    savePort;
  2257.     PenState    savePen;
  2258.     short        buttonOval;
  2259.     Boolean        isColorPort;
  2260.  
  2261.     const short kColorPort = 0xC000;
  2262.  
  2263.     GetDialogItem(theDialog, kOKButton, &itemKind, &itemHandle, &itemRect);
  2264.  
  2265.     GetPort(&savePort);
  2266.     buttonWindow = (**(ControlHandle)itemHandle).contrlOwner;
  2267.     SetPort(buttonWindow);
  2268.     GetPenState(&savePen);
  2269.     PenNormal();
  2270.  
  2271.     InsetRect(&itemRect, -4, -4);
  2272.     FrameRoundRect(&itemRect, 16, 16);
  2273.     buttonOval = ((itemRect.bottom - itemRect.top)/2)+2;
  2274.  
  2275.     isColorPort = ((((CGrafPtr)buttonWindow)->portVersion & kColorPort) == kColorPort);
  2276.     
  2277.     if ( (**(ControlHandle)itemHandle).contrlHilite == kControlInactive )
  2278.     {
  2279.         // Button is inactive, so outline with gray
  2280.  
  2281.         RGBColor    fgSaveColor;
  2282.         RGBColor    fgNewColor;
  2283.         RGBColor    bgColor;
  2284.         Boolean        newGray = false;
  2285.  
  2286.         if ( isColorPort )
  2287.         {
  2288.             GetBackColor(&bgColor);
  2289.             GetForeColor(&fgSaveColor);
  2290.             fgNewColor = fgSaveColor;
  2291.             
  2292.             Rect globalRect = itemRect;
  2293.             LocalToGlobal((Point *)&(globalRect.top));
  2294.             LocalToGlobal((Point *)&(globalRect.bottom));
  2295.             GDHandle targetDevice = GetMaxDevice(&globalRect);
  2296.             
  2297.             newGray = GetGray(targetDevice, &bgColor, &fgNewColor);
  2298.         }
  2299.  
  2300.         if ( newGray )
  2301.             RGBForeColor(&fgNewColor);
  2302.         else
  2303. #ifdef THINK_CPLUS
  2304.             PenPat(ODQDGlobals.gray);
  2305. #else
  2306.             PenPat(&ODQDGlobals.gray);
  2307. #endif
  2308.  
  2309.         PenSize(3, 3);
  2310.         FrameRoundRect(&itemRect, buttonOval, buttonOval);
  2311.         
  2312.         if ( isColorPort )
  2313.             RGBForeColor(&fgSaveColor);
  2314.     }
  2315.     else
  2316.     {
  2317.         // Button is active, so outline with black
  2318. #ifdef THINK_CPLUS
  2319.         PenPat(ODQDGlobals.black);
  2320. #else
  2321.         PenPat(&ODQDGlobals.black);
  2322. #endif
  2323.         PenSize(3, 3);
  2324.         FrameRoundRect(&itemRect, buttonOval, buttonOval);
  2325.     }
  2326.  
  2327.     SetPenState(&savePen);
  2328.     SetPort(savePort);
  2329. }
  2330. //------------------------------------------------------------------------------
  2331. // AttachUserItemProc
  2332. //------------------------------------------------------------------------------
  2333.  
  2334. static void AttachUserItemProc (DialogPtr dlog, short item, UserItemUPP proc)
  2335. {
  2336.     Rect        itemRect;
  2337.     short        itemType;
  2338.     Handle        itemHandle;
  2339.     
  2340.     GetDialogItem (dlog, item, &itemType, &itemHandle, &itemRect);
  2341.     SetDialogItem (dlog, item, itemType, (Handle) proc, &itemRect);
  2342. }
  2343.  
  2344. //------------------------------------------------------------------------------
  2345. // SetNumText
  2346. //------------------------------------------------------------------------------
  2347.  
  2348. ODStatic void SetNumText(DialogPtr dlg, ODSShort item, ODSLong numValue)
  2349. {
  2350.     short    itemType;
  2351.     Handle    itemHandle;
  2352.     Rect    itemRect;
  2353.     Str255    text;
  2354.  
  2355.     NumToString(numValue, text);
  2356.     GetDialogItem(dlg, item, &itemType, &itemHandle, &itemRect);
  2357.     SetDialogItemText(itemHandle,text);
  2358.  
  2359. }
  2360.  
  2361. //------------------------------------------------------------------------------
  2362. //------------------------------------------------------------------------------
  2363.  
  2364. // dh - The following functions that start with DH were taken from the Info dialog 
  2365. // code. Should this be factored so that we can share this instead of copying it?
  2366.  
  2367. ODStatic ODULong    DHGetPreferredSizeInSIZE(PlatformFile* file, ODSShort resourceID)
  2368. {
  2369. // returns 0 if the resource is not found
  2370.     ODULong size = 0;
  2371.     ODPtr sizeRes =
  2372.         file->ReadResourcePtr(kSIZERsrcType, resourceID, kODNULL);
  2373.     if (sizeRes != kODNULL)
  2374.     {
  2375.         memcpy(&size, ((char*)sizeRes)+2, sizeof(size)); // Should probably use a constant.
  2376.         ODDisposePtr(sizeRes);                             // No argument here.
  2377.     }
  2378.     return size / 1024;
  2379. }
  2380.  
  2381. ODStatic void     DHSetPreferredSizeInSIZE(PlatformFile* file, ODSShort resourceID, 
  2382.         PlatformFile* fromFile, ODSShort fromResID, ODULong numKBytes)
  2383. {
  2384.     if (fromFile == kODNULL)
  2385.         fromFile = file;
  2386.     ODULong sizeOfResource;
  2387.     ODPtr sizeRes =
  2388.         fromFile->ReadResourcePtr(kSIZERsrcType, fromResID, &sizeOfResource);
  2389.     
  2390.     if (sizeRes != kODNULL)
  2391.     {
  2392.         numKBytes *= 1024; // Should probably use a constant.
  2393.         memcpy(((char*)sizeRes)+2, &numKBytes, sizeof(numKBytes)); // Should probably use a constant.
  2394.     
  2395.         file->WriteResourcePtr(kSIZERsrcType, resourceID, sizeRes, sizeOfResource);
  2396.         ODDisposePtr(sizeRes);
  2397.     }
  2398. }
  2399.  
  2400. ODStatic ODULong    DHGetDocumentPreferredHeapSize(PlatformFile* file)
  2401. {
  2402.     // returns 0 if there is no preferred size    
  2403.     return DHGetPreferredSizeInSIZE(file, 0); // Should probably use a constant.
  2404. }
  2405.  
  2406. ODStatic void        DHClearDocumentPreferredHeapSize(PlatformFile* file)
  2407. {
  2408.     file->DeleteResource(kSIZERsrcType, 0); // Should probably use constants.
  2409.     file->DeleteResource(kSIZERsrcType, 1);
  2410. }
  2411.  
  2412.  
  2413. ODStatic void        DHSetDocumentPreferredHeapSize(PlatformFile* file, ODULong numKBytes)
  2414. {
  2415.     DHSetPreferredSizeInSIZE(file, 0, kODNULL, -1, numKBytes); // Should probably use constants.
  2416.     DHSetPreferredSizeInSIZE(file, 1, kODNULL, -1, numKBytes);
  2417. }
  2418.  
  2419. ODError CStackPtrList::Add( ODPtr theItem )
  2420. {  
  2421.     ODError returnErr = noErr;
  2422.     
  2423.     if( numListItems == maxListItems )
  2424.         returnErr =  kODErrValueOutOfRange;
  2425.     else
  2426.     {
  2427.         data[numListItems] = theItem;
  2428.         numListItems++;
  2429.     }
  2430.     
  2431.     return returnErr; 
  2432. }
  2433.  
  2434. ODPtr CStackPtrList::Next( void )
  2435. {
  2436.     if( ( nextPos > maxListItems -  1 ) || ( nextPos > numListItems -1 ) )
  2437.         return (ODPtr)kODNULL;
  2438.     else
  2439.         return data[nextPos++];
  2440. }
  2441.  
  2442.  
  2443.